1 /* drivers/gpu/arm/.../platform/gpu_pmqos.c
3 * Copyright 2011 by S.LSI. Samsung Electronics Inc.
4 * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea
6 * Samsung SoC Mali-T Series DVFS driver
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.
18 #include <mali_kbase.h>
20 #include <linux/pm_qos.h>
22 #include "mali_kbase_platform.h"
23 #include "gpu_dvfs_handler.h"
25 #if defined(PM_QOS_CLUSTER2_FREQ_MAX_DEFAULT_VALUE)
26 #define PM_QOS_CPU_CLUSTER_NUM 3
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
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
;
44 #ifdef CONFIG_MALI_SUSTAINABLE_OPT
45 struct pm_qos_request exynos5_g3d_cpu_cluster0_max_qos
;
48 extern struct kbase_device
*pkbdev
;
50 #ifdef CONFIG_MALI_PM_QOS
51 int gpu_pm_qos_command(struct exynos_context
*platform
, gpu_pmqos_state state
)
55 DVFS_ASSERT(platform
);
57 #ifdef CONFIG_MALI_ASV_CALIBRATION_SUPPORT
58 if (platform
->gpu_auto_cali_status
)
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);
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
);
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;
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
);
103 platform
->is_pm_qos_init
= false;
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__
);
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
);
120 mutex_unlock(&platform
->gpu_vk_boost_lock
);
122 pm_qos_update_request(&exynos5_g3d_cpu_cluster0_min_qos
, platform
->table
[platform
->step
].cpu_little_min_freq
);
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]);
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
);
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
);
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__
);
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
);
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__
);
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
;
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
;
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__
);
195 for (idx
= 0; idx
< platform
->table_size
; idx
++)
196 platform
->table
[idx
].cpu_big_max_freq
= platform
->save_cpu_max_freq
[idx
];