2 * This confidential and proprietary software may be used only as
3 * authorised by a licensing agreement from ARM Limited
4 * (C) COPYRIGHT 2013-2014 ARM Limited
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.
12 * @file arm_core_scaling.c
13 * Example core scaling policy.
16 /* #define ENABLE_DEBUG_LOG */
17 #include "custom_log.h"
19 #include "arm_core_scaling.h"
21 #include <linux/mali/mali_utgard.h>
22 #include "mali_kernel_common.h"
24 #include <linux/workqueue.h>
26 static int num_cores_total;
27 static int num_cores_enabled;
30 * 对连续的 request_to_disable_on_core 的计数.
32 static int count_of_requests_to_disable_one_core;
34 * 在 count_of_requests_to_disable_one_core 等于本 value 的时候,
35 * 将执行确实的 disable_one_core 操作.
37 #define NUM_OF_REQUESTS_TO_REALLY_DISABLE_ONE_CORE (10)
39 static struct work_struct wq_work;
41 static void set_num_cores(struct work_struct *work)
43 int err = mali_perf_set_num_pp_cores(num_cores_enabled);
45 MALI_DEBUG_ASSERT(0 == err);
49 static void enable_one_core(void)
51 if (num_cores_enabled < num_cores_total) {
53 schedule_work(&wq_work);
54 MALI_DEBUG_PRINT(3, ("Core scaling: Enabling one more core\n"));
57 MALI_DEBUG_ASSERT(1 <= num_cores_enabled);
58 MALI_DEBUG_ASSERT(num_cores_total >= num_cores_enabled);
61 static void disable_one_core(void)
63 if (1 < num_cores_enabled) {
65 schedule_work(&wq_work);
66 MALI_DEBUG_PRINT(3, ("Core scaling: Disabling one core\n"));
69 MALI_DEBUG_ASSERT(1 <= num_cores_enabled);
70 MALI_DEBUG_ASSERT(num_cores_total >= num_cores_enabled);
73 static void enable_max_num_cores(void)
75 if (num_cores_enabled < num_cores_total) {
76 num_cores_enabled = num_cores_total;
77 schedule_work(&wq_work);
79 ("Core scaling: Enabling max num of cores\n"));
82 MALI_DEBUG_ASSERT(num_cores_total == num_cores_enabled);
85 void mali_core_scaling_init(int num_pp_cores)
87 INIT_WORK(&wq_work, set_num_cores);
89 num_cores_total = num_pp_cores;
90 num_cores_enabled = num_pp_cores;
92 /* NOTE: Mali is not fully initialized at this point. */
95 void mali_core_scaling_sync(int num_cores)
97 num_cores_enabled = num_cores;
100 void mali_core_scaling_term(void)
102 flush_scheduled_work();
105 #define PERCENT_OF(percent, max) ((int) ((percent)*(max)/100.0 + 0.5))
107 void mali_core_scaling_update(struct mali_gpu_utilization_data *data)
110 * This function implements a very trivial PP core scaling algorithm.
112 * It is _NOT_ of production quality.
113 * The only intention behind this algorithm is to exercise and test the
114 * core scaling functionality of the driver.
115 * It is _NOT_ tuned for neither power saving nor performance!
117 * Other metrics than PP utilization need to be considered as well
118 * in order to make a good core scaling algorithm.
122 ("Utilization:(%3d, %3d, %3d), cores enabled: %d/%d\n",
123 data->utilization_gpu,
124 data->utilization_gp,
125 data->utilization_pp,
131 * is normally called directly
132 * from the utilization callback
133 * which is in timer context. */
135 if (PERCENT_OF(90, 256) < data->utilization_pp) {
136 V("to enable max num of pp_cores.");
137 enable_max_num_cores();
138 count_of_requests_to_disable_one_core = 0;
139 } else if (PERCENT_OF(50, 256) < data->utilization_pp) {
140 V("to enable more one pp_core.");
142 count_of_requests_to_disable_one_core = 0;
143 } else if (PERCENT_OF(40, 256) < data->utilization_pp) {
144 count_of_requests_to_disable_one_core = 0;
145 } else if (PERCENT_OF(0, 256) < data->utilization_pp) {
146 count_of_requests_to_disable_one_core++;
147 if (count_of_requests_to_disable_one_core
148 >= NUM_OF_REQUESTS_TO_REALLY_DISABLE_ONE_CORE) {
149 V("to disable a pp_core.");
151 count_of_requests_to_disable_one_core = 0;
154 count_of_requests_to_disable_one_core = 0;