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 (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
);
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;
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
);
101 platform
->is_pm_qos_init
= false;
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__
);
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
);
118 mutex_unlock(&platform
->gpu_vk_boost_lock
);
120 pm_qos_update_request(&exynos5_g3d_cpu_cluster0_min_qos
, platform
->table
[platform
->step
].cpu_little_min_freq
);
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]);
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
);
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
);
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__
);
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
);
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__
);
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
;
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
;
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__
);
193 for (idx
= 0; idx
< platform
->table_size
; idx
++)
194 platform
->table
[idx
].cpu_big_max_freq
= platform
->save_cpu_max_freq
[idx
];