5f804fd0af9b1d0b60c35801ab6b7fe35ae63595
[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 (platform->boost_egl_min_lock)
70 pm_qos_add_request(&exynos5_g3d_cpu_cluster1_min_qos, PM_QOS_CLUSTER1_FREQ_MIN, 0);
71 #if PM_QOS_CPU_CLUSTER_NUM == 3
72 pm_qos_add_request(&exynos5_g3d_cpu_cluster1_min_qos, PM_QOS_CLUSTER1_FREQ_MIN, 0);
73 pm_qos_add_request(&exynos5_g3d_cpu_cluster2_max_qos, PM_QOS_CLUSTER2_FREQ_MAX, PM_QOS_CLUSTER2_FREQ_MAX_DEFAULT_VALUE);
74 if (platform->boost_egl_min_lock)
75 pm_qos_add_request(&exynos5_g3d_cpu_cluster2_min_qos, PM_QOS_CLUSTER2_FREQ_MIN, 0);
76 #ifdef CONFIG_MALI_SUSTAINABLE_OPT
77 pm_qos_add_request(&exynos5_g3d_cpu_cluster0_max_qos, PM_QOS_CLUSTER0_FREQ_MAX, PM_QOS_CLUSTER0_FREQ_MAX_DEFAULT_VALUE);
78 #endif
79 #endif
80 for (idx = 0; idx < platform->table_size; idx++)
81 platform->save_cpu_max_freq[idx] = platform->table[idx].cpu_big_max_freq;
82 platform->is_pm_qos_init = true;
83 break;
84 case GPU_CONTROL_PM_QOS_DEINIT:
85 pm_qos_remove_request(&exynos5_g3d_mif_min_qos);
86 if (platform->pmqos_mif_max_clock)
87 pm_qos_remove_request(&exynos5_g3d_mif_max_qos);
88 pm_qos_remove_request(&exynos5_g3d_cpu_cluster0_min_qos);
89 pm_qos_remove_request(&exynos5_g3d_cpu_cluster1_max_qos);
90 if (platform->boost_egl_min_lock)
91 pm_qos_remove_request(&exynos5_g3d_cpu_cluster1_min_qos);
92 #if PM_QOS_CPU_CLUSTER_NUM == 3
93 pm_qos_remove_request(&exynos5_g3d_cpu_cluster1_min_qos);
94 pm_qos_remove_request(&exynos5_g3d_cpu_cluster2_max_qos);
95 if (platform->boost_egl_min_lock)
96 pm_qos_remove_request(&exynos5_g3d_cpu_cluster2_min_qos);
97 #ifdef CONFIG_MALI_SUSTAINABLE_OPT
98 pm_qos_remove_request(&exynos5_g3d_cpu_cluster0_max_qos);
99 #endif
100 #endif
101 platform->is_pm_qos_init = false;
102 break;
103 case GPU_CONTROL_PM_QOS_SET:
104 if (!platform->is_pm_qos_init) {
105 GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: PM QOS ERROR : pm_qos deinit -> set\n", __func__);
106 return -ENOENT;
107 }
108 KBASE_DEBUG_ASSERT(platform->step >= 0);
109 pm_qos_update_request(&exynos5_g3d_mif_min_qos, platform->table[platform->step].mem_freq);
110 if (platform->pmqos_mif_max_clock &&
111 (platform->table[platform->step].clock >= platform->pmqos_mif_max_clock_base))
112 pm_qos_update_request(&exynos5_g3d_mif_max_qos, platform->pmqos_mif_max_clock);
113 #ifdef CONFIG_MALI_VK_BOOST /* VK JOB Boost */
114 mutex_lock(&platform->gpu_vk_boost_lock);
115 if (platform->ctx_vk_need_qos && platform->max_lock == platform->gpu_vk_boost_max_clk_lock) {
116 pm_qos_update_request(&exynos5_g3d_mif_min_qos, platform->gpu_vk_boost_mif_min_clk_lock);
117 }
118 mutex_unlock(&platform->gpu_vk_boost_lock);
119 #endif
120 pm_qos_update_request(&exynos5_g3d_cpu_cluster0_min_qos, platform->table[platform->step].cpu_little_min_freq);
121
122 if (!platform->boost_is_enabled)
123 pm_qos_update_request(&exynos5_g3d_cpu_cluster1_max_qos, platform->table[platform->step].cpu_big_max_freq);
124 #if PM_QOS_CPU_CLUSTER_NUM == 3
125 pm_qos_update_request(&exynos5_g3d_cpu_cluster1_min_qos, platform->table[platform->step].cpu_middle_min_freq);
126 if (!platform->boost_is_enabled)
127 pm_qos_update_request(&exynos5_g3d_cpu_cluster2_max_qos, platform->table[platform->step].cpu_big_max_freq);
128 #ifdef CONFIG_MALI_SUSTAINABLE_OPT
129 if (platform->sustainable.info_array[0] > 0) {
130 if (((platform->cur_clock == platform->sustainable.info_array[0])
131 || (platform->max_lock == platform->sustainable.info_array[0]))
132 && platform->env_data.utilization > platform->sustainable.info_array[1]) {
133 platform->sustainable.status = true;
134 pm_qos_update_request(&exynos5_g3d_cpu_cluster0_max_qos, platform->sustainable.info_array[2]);
135 pm_qos_update_request(&exynos5_g3d_cpu_cluster1_max_qos, platform->sustainable.info_array[3]);
136 pm_qos_update_request(&exynos5_g3d_cpu_cluster2_max_qos, platform->sustainable.info_array[4]);
137 } else {
138 platform->sustainable.status = false;
139 pm_qos_update_request(&exynos5_g3d_cpu_cluster0_max_qos, PM_QOS_CLUSTER0_FREQ_MAX_DEFAULT_VALUE);
140 pm_qos_update_request(&exynos5_g3d_cpu_cluster1_max_qos, PM_QOS_CLUSTER1_FREQ_MAX_DEFAULT_VALUE);
141 pm_qos_update_request(&exynos5_g3d_cpu_cluster2_max_qos, platform->table[platform->step].cpu_big_max_freq);
142 }
143 }
144 #endif
145 #ifdef CONFIG_MALI_SEC_CL_BOOST
146 if (pkbdev->pm.backend.metrics.is_full_compute_util && platform->cl_boost_disable == false)
147 pm_qos_update_request(&exynos5_g3d_cpu_cluster2_max_qos, PM_QOS_CLUSTER2_FREQ_MAX_DEFAULT_VALUE);
148 #endif
149 #endif
150
151 break;
152 case GPU_CONTROL_PM_QOS_RESET:
153 if (!platform->is_pm_qos_init) {
154 GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: PM QOS ERROR : pm_qos deinit -> reset\n", __func__);
155 return -ENOENT;
156 }
157 pm_qos_update_request(&exynos5_g3d_mif_min_qos, 0);
158 if (platform->pmqos_mif_max_clock)
159 pm_qos_update_request(&exynos5_g3d_mif_max_qos, PM_QOS_BUS_THROUGHPUT_MAX_DEFAULT_VALUE);
160 pm_qos_update_request(&exynos5_g3d_cpu_cluster0_min_qos, 0);
161 pm_qos_update_request(&exynos5_g3d_cpu_cluster1_max_qos, PM_QOS_CLUSTER1_FREQ_MAX_DEFAULT_VALUE);
162 #if PM_QOS_CPU_CLUSTER_NUM == 3
163 pm_qos_update_request(&exynos5_g3d_cpu_cluster1_min_qos, 0);
164 pm_qos_update_request(&exynos5_g3d_cpu_cluster2_max_qos, PM_QOS_CLUSTER2_FREQ_MAX_DEFAULT_VALUE);
165 #ifdef CONFIG_MALI_SUSTAINABLE_OPT
166 pm_qos_update_request(&exynos5_g3d_cpu_cluster0_max_qos, PM_QOS_CLUSTER0_FREQ_MAX_DEFAULT_VALUE);
167 pm_qos_update_request(&exynos5_g3d_cpu_cluster1_max_qos, PM_QOS_CLUSTER1_FREQ_MAX_DEFAULT_VALUE);
168 pm_qos_update_request(&exynos5_g3d_cpu_cluster2_max_qos, PM_QOS_CLUSTER2_FREQ_MAX_DEFAULT_VALUE);
169 #endif
170 #endif
171 break;
172 case GPU_CONTROL_PM_QOS_EGL_SET:
173 if (!platform->is_pm_qos_init) {
174 GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: PM QOS ERROR : pm_qos deinit -> egl_set\n", __func__);
175 return -ENOENT;
176 }
177 pm_qos_update_request_timeout(&exynos5_g3d_cpu_cluster1_min_qos, platform->boost_egl_min_lock, 30000);
178 for (idx = 0; idx < platform->table_size; idx++) {
179 platform->table[idx].cpu_big_max_freq = PM_QOS_CLUSTER1_FREQ_MAX_DEFAULT_VALUE;
180 }
181 #if PM_QOS_CPU_CLUSTER_NUM == 3
182 pm_qos_update_request_timeout(&exynos5_g3d_cpu_cluster2_min_qos, platform->boost_egl_min_lock, 30000);
183 for (idx = 0; idx < platform->table_size; idx++) {
184 platform->table[idx].cpu_big_max_freq = PM_QOS_CLUSTER2_FREQ_MAX_DEFAULT_VALUE;
185 }
186 #endif
187 break;
188 case GPU_CONTROL_PM_QOS_EGL_RESET:
189 if (!platform->is_pm_qos_init) {
190 GPU_LOG(DVFS_ERROR, DUMMY, 0u, 0u, "%s: PM QOS ERROR : pm_qos deinit -> egl_reset\n", __func__);
191 return -ENOENT;
192 }
193 for (idx = 0; idx < platform->table_size; idx++)
194 platform->table[idx].cpu_big_max_freq = platform->save_cpu_max_freq[idx];
195 break;
196 default:
197 break;
198 }
199
200 return 0;
201 }
202 #endif