source: G950FXXS5DSI1
[GitHub/exynos8895/android_kernel_samsung_universal8895.git] / drivers / gpu / arm / b_r16p0 / platform / exynos / gpu_pmqos.c
1 /* drivers/gpu/arm/.../platform/gpu_pmqos.c
2 *
3 * Copyright 2011 by S.LSI. Samsung Electronics Inc.
4 * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea
5 *
6 * Samsung SoC Mali-T Series DVFS driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software FoundatIon.
11 */
12
13 /**
14 * @file gpu_pmqos.c
15 * DVFS
16 */
17
18 #include <mali_kbase.h>
19
20 #include <linux/pm_qos.h>
21
22 #include "mali_kbase_platform.h"
23 #include "gpu_dvfs_handler.h"
24
25 #if defined(PM_QOS_CLUSTER2_FREQ_MAX_DEFAULT_VALUE)
26 #define PM_QOS_CPU_CLUSTER_NUM 3
27 #else
28 #define PM_QOS_CPU_CLUSTER_NUM 2
29 #ifndef PM_QOS_CLUSTER1_FREQ_MAX_DEFAULT_VALUE
30 #define PM_QOS_CLUSTER1_FREQ_MAX_DEFAULT_VALUE INT_MAX
31 #endif
32 #endif
33
34 struct pm_qos_request exynos5_g3d_mif_min_qos;
35 struct pm_qos_request exynos5_g3d_mif_max_qos;
36 struct pm_qos_request exynos5_g3d_cpu_cluster0_min_qos;
37 struct pm_qos_request exynos5_g3d_cpu_cluster1_max_qos;
38 struct pm_qos_request exynos5_g3d_cpu_cluster1_min_qos;
39 #if PM_QOS_CPU_CLUSTER_NUM == 3
40 struct pm_qos_request exynos5_g3d_cpu_cluster2_max_qos;
41 struct pm_qos_request exynos5_g3d_cpu_cluster2_min_qos;
42 #endif
43
44 #ifdef CONFIG_MALI_SUSTAINABLE_OPT
45 struct pm_qos_request exynos5_g3d_cpu_cluster0_max_qos;
46 #endif
47
48 extern struct kbase_device *pkbdev;
49
50 #ifdef CONFIG_MALI_PM_QOS
51 int gpu_pm_qos_command(struct exynos_context *platform, gpu_pmqos_state state)
52 {
53 int idx;
54
55 DVFS_ASSERT(platform);
56
57 #ifdef CONFIG_MALI_ASV_CALIBRATION_SUPPORT
58 if (platform->gpu_auto_cali_status)
59 return 0;
60 #endif
61
62 switch (state) {
63 case GPU_CONTROL_PM_QOS_INIT:
64 pm_qos_add_request(&exynos5_g3d_mif_min_qos, PM_QOS_BUS_THROUGHPUT, 0);
65 if (platform->pmqos_mif_max_clock)
66 pm_qos_add_request(&exynos5_g3d_mif_max_qos, PM_QOS_BUS_THROUGHPUT_MAX, PM_QOS_BUS_THROUGHPUT_MAX_DEFAULT_VALUE);
67 pm_qos_add_request(&exynos5_g3d_cpu_cluster0_min_qos, PM_QOS_CLUSTER0_FREQ_MIN, 0);
68 pm_qos_add_request(&exynos5_g3d_cpu_cluster1_max_qos, PM_QOS_CLUSTER1_FREQ_MAX, PM_QOS_CLUSTER1_FREQ_MAX_DEFAULT_VALUE);
69 #if PM_QOS_CPU_CLUSTER_NUM == 2
70 if (platform->boost_egl_min_lock)
71 pm_qos_add_request(&exynos5_g3d_cpu_cluster1_min_qos, PM_QOS_CLUSTER1_FREQ_MIN, 0);
72 #endif
73 #if PM_QOS_CPU_CLUSTER_NUM == 3
74 pm_qos_add_request(&exynos5_g3d_cpu_cluster1_min_qos, PM_QOS_CLUSTER1_FREQ_MIN, 0);
75 pm_qos_add_request(&exynos5_g3d_cpu_cluster2_max_qos, PM_QOS_CLUSTER2_FREQ_MAX, PM_QOS_CLUSTER2_FREQ_MAX_DEFAULT_VALUE);
76 if (platform->boost_egl_min_lock)
77 pm_qos_add_request(&exynos5_g3d_cpu_cluster2_min_qos, PM_QOS_CLUSTER2_FREQ_MIN, 0);
78 #ifdef CONFIG_MALI_SUSTAINABLE_OPT
79 pm_qos_add_request(&exynos5_g3d_cpu_cluster0_max_qos, PM_QOS_CLUSTER0_FREQ_MAX, PM_QOS_CLUSTER0_FREQ_MAX_DEFAULT_VALUE);
80 #endif
81 #endif
82 for (idx = 0; idx < platform->table_size; idx++)
83 platform->save_cpu_max_freq[idx] = platform->table[idx].cpu_big_max_freq;
84 platform->is_pm_qos_init = true;
85 break;
86 case GPU_CONTROL_PM_QOS_DEINIT:
87 pm_qos_remove_request(&exynos5_g3d_mif_min_qos);
88 if (platform->pmqos_mif_max_clock)
89 pm_qos_remove_request(&exynos5_g3d_mif_max_qos);
90 pm_qos_remove_request(&exynos5_g3d_cpu_cluster0_min_qos);
91 pm_qos_remove_request(&exynos5_g3d_cpu_cluster1_max_qos);
92 if (platform->boost_egl_min_lock)
93 pm_qos_remove_request(&exynos5_g3d_cpu_cluster1_min_qos);
94 #if PM_QOS_CPU_CLUSTER_NUM == 3
95 pm_qos_remove_request(&exynos5_g3d_cpu_cluster1_min_qos);
96 pm_qos_remove_request(&exynos5_g3d_cpu_cluster2_max_qos);
97 if (platform->boost_egl_min_lock)
98 pm_qos_remove_request(&exynos5_g3d_cpu_cluster2_min_qos);
99 #ifdef CONFIG_MALI_SUSTAINABLE_OPT
100 pm_qos_remove_request(&exynos5_g3d_cpu_cluster0_max_qos);
101 #endif
102 #endif
103 platform->is_pm_qos_init = false;
104 break;
105 case GPU_CONTROL_PM_QOS_SET:
106 if (!platform->is_pm_qos_init) {
107 GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: PM QOS ERROR : pm_qos deinit -> set\n", __func__);
108 return -ENOENT;
109 }
110 KBASE_DEBUG_ASSERT(platform->step >= 0);
111 pm_qos_update_request(&exynos5_g3d_mif_min_qos, platform->table[platform->step].mem_freq);
112 if (platform->pmqos_mif_max_clock &&
113 (platform->table[platform->step].clock >= platform->pmqos_mif_max_clock_base))
114 pm_qos_update_request(&exynos5_g3d_mif_max_qos, platform->pmqos_mif_max_clock);
115 #ifdef CONFIG_MALI_VK_BOOST /* VK JOB Boost */
116 mutex_lock(&platform->gpu_vk_boost_lock);
117 if (platform->ctx_vk_need_qos && platform->max_lock == platform->gpu_vk_boost_max_clk_lock) {
118 pm_qos_update_request(&exynos5_g3d_mif_min_qos, platform->gpu_vk_boost_mif_min_clk_lock);
119 }
120 mutex_unlock(&platform->gpu_vk_boost_lock);
121 #endif
122 pm_qos_update_request(&exynos5_g3d_cpu_cluster0_min_qos, platform->table[platform->step].cpu_little_min_freq);
123
124 if (!platform->boost_is_enabled)
125 pm_qos_update_request(&exynos5_g3d_cpu_cluster1_max_qos, platform->table[platform->step].cpu_big_max_freq);
126 #if PM_QOS_CPU_CLUSTER_NUM == 3
127 pm_qos_update_request(&exynos5_g3d_cpu_cluster1_min_qos, platform->table[platform->step].cpu_middle_min_freq);
128 if (!platform->boost_is_enabled)
129 pm_qos_update_request(&exynos5_g3d_cpu_cluster2_max_qos, platform->table[platform->step].cpu_big_max_freq);
130 #ifdef CONFIG_MALI_SUSTAINABLE_OPT
131 if (platform->sustainable.info_array[0] > 0) {
132 if (((platform->cur_clock == platform->sustainable.info_array[0])
133 || (platform->max_lock == platform->sustainable.info_array[0]))
134 && platform->env_data.utilization > platform->sustainable.info_array[1]) {
135 platform->sustainable.status = true;
136 pm_qos_update_request(&exynos5_g3d_cpu_cluster0_max_qos, platform->sustainable.info_array[2]);
137 pm_qos_update_request(&exynos5_g3d_cpu_cluster1_max_qos, platform->sustainable.info_array[3]);
138 pm_qos_update_request(&exynos5_g3d_cpu_cluster2_max_qos, platform->sustainable.info_array[4]);
139 } else {
140 platform->sustainable.status = false;
141 pm_qos_update_request(&exynos5_g3d_cpu_cluster0_max_qos, PM_QOS_CLUSTER0_FREQ_MAX_DEFAULT_VALUE);
142 pm_qos_update_request(&exynos5_g3d_cpu_cluster1_max_qos, PM_QOS_CLUSTER1_FREQ_MAX_DEFAULT_VALUE);
143 pm_qos_update_request(&exynos5_g3d_cpu_cluster2_max_qos, platform->table[platform->step].cpu_big_max_freq);
144 }
145 }
146 #endif
147 #ifdef CONFIG_MALI_SEC_CL_BOOST
148 if (pkbdev->pm.backend.metrics.is_full_compute_util && platform->cl_boost_disable == false)
149 pm_qos_update_request(&exynos5_g3d_cpu_cluster2_max_qos, PM_QOS_CLUSTER2_FREQ_MAX_DEFAULT_VALUE);
150 #endif
151 #endif
152
153 break;
154 case GPU_CONTROL_PM_QOS_RESET:
155 if (!platform->is_pm_qos_init) {
156 GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: PM QOS ERROR : pm_qos deinit -> reset\n", __func__);
157 return -ENOENT;
158 }
159 pm_qos_update_request(&exynos5_g3d_mif_min_qos, 0);
160 if (platform->pmqos_mif_max_clock)
161 pm_qos_update_request(&exynos5_g3d_mif_max_qos, PM_QOS_BUS_THROUGHPUT_MAX_DEFAULT_VALUE);
162 pm_qos_update_request(&exynos5_g3d_cpu_cluster0_min_qos, 0);
163 pm_qos_update_request(&exynos5_g3d_cpu_cluster1_max_qos, PM_QOS_CLUSTER1_FREQ_MAX_DEFAULT_VALUE);
164 #if PM_QOS_CPU_CLUSTER_NUM == 3
165 pm_qos_update_request(&exynos5_g3d_cpu_cluster1_min_qos, 0);
166 pm_qos_update_request(&exynos5_g3d_cpu_cluster2_max_qos, PM_QOS_CLUSTER2_FREQ_MAX_DEFAULT_VALUE);
167 #ifdef CONFIG_MALI_SUSTAINABLE_OPT
168 pm_qos_update_request(&exynos5_g3d_cpu_cluster0_max_qos, PM_QOS_CLUSTER0_FREQ_MAX_DEFAULT_VALUE);
169 pm_qos_update_request(&exynos5_g3d_cpu_cluster1_max_qos, PM_QOS_CLUSTER1_FREQ_MAX_DEFAULT_VALUE);
170 pm_qos_update_request(&exynos5_g3d_cpu_cluster2_max_qos, PM_QOS_CLUSTER2_FREQ_MAX_DEFAULT_VALUE);
171 #endif
172 #endif
173 break;
174 case GPU_CONTROL_PM_QOS_EGL_SET:
175 if (!platform->is_pm_qos_init) {
176 GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: PM QOS ERROR : pm_qos deinit -> egl_set\n", __func__);
177 return -ENOENT;
178 }
179 pm_qos_update_request_timeout(&exynos5_g3d_cpu_cluster1_min_qos, platform->boost_egl_min_lock, 30000);
180 for (idx = 0; idx < platform->table_size; idx++) {
181 platform->table[idx].cpu_big_max_freq = PM_QOS_CLUSTER1_FREQ_MAX_DEFAULT_VALUE;
182 }
183 #if PM_QOS_CPU_CLUSTER_NUM == 3
184 pm_qos_update_request_timeout(&exynos5_g3d_cpu_cluster2_min_qos, platform->boost_egl_min_lock, 30000);
185 for (idx = 0; idx < platform->table_size; idx++) {
186 platform->table[idx].cpu_big_max_freq = PM_QOS_CLUSTER2_FREQ_MAX_DEFAULT_VALUE;
187 }
188 #endif
189 break;
190 case GPU_CONTROL_PM_QOS_EGL_RESET:
191 if (!platform->is_pm_qos_init) {
192 GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: PM QOS ERROR : pm_qos deinit -> egl_reset\n", __func__);
193 return -ENOENT;
194 }
195 for (idx = 0; idx < platform->table_size; idx++)
196 platform->table[idx].cpu_big_max_freq = platform->save_cpu_max_freq[idx];
197 break;
198 default:
199 break;
200 }
201
202 return 0;
203 }
204 #endif