pass-hal: tm2: Add missing LICENSE file and license information
[platform/adaptation/tm2/pass-hal-tm2.git] / src / gpu / gpu.c
1 /*
2  * PASS (Power Aware System Service)
3  *
4  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the License);
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 #include <errno.h>
19 #include <limits.h>
20 #include <pass/hal.h>
21 #include <pass/hal-log.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include "../shared/sysfs.h"
27
28 /* TODO: Version! */
29 #define HAL_VERSION     MAKE_2B_CODE_4(VER_MAJOR,VER_MINOR,VER_REVISION,VER_RELEASE)
30 #define DEV_VERSION_GPU MAKE_2B_CODE_2(1,0)
31
32 #define DEVFREQ_GPU_PATH_PREFIX                 "/sys/class/devfreq/"
33 #define DEVFREQ_GPU_CURR_GOVERNOR_PATH_SUFFIX   "/governor"
34 #define DEVFREQ_GPU_CURR_FREQ_PATH_SUFFIX       "/cur_freq"
35 #define DEVFREQ_GPU_MIN_FREQ_PATH_SUFFIX        "/min_freq"
36 #define DEVFREQ_GPU_MAX_FREQ_PATH_SUFFIX        "/max_freq"
37
38 #define TMU_PATH_PREFIX                         "/sys/class/thermal/thermal_zone"
39 #define TMU_TEMP_PATH_SUFFIX                    "/temp"
40 #define TMU_POLICY_PATH_SUFFIX                  "/policy"
41
42 #define TM2_GPU_THERMAL_ZONE_NUM                2
43
44 static int tm2_dvfs_get_curr_governor(char *res_name, char *governor)
45 {
46         char path[PATH_MAX];
47         int ret;
48
49         if ((!res_name) || (!governor))
50                 return -EINVAL;
51
52         snprintf(path, PATH_MAX, "%s%s%s",
53                 DEVFREQ_GPU_PATH_PREFIX,
54                 res_name,
55                 DEVFREQ_GPU_CURR_GOVERNOR_PATH_SUFFIX);
56
57         ret = sysfs_read_str(path, governor, BUFF_MAX);
58         if (ret < 0)
59                 return ret;
60
61         return 0;
62 }
63
64 static int tm2_dvfs_set_curr_governor(char *res_name, char *governor)
65 {
66         char path[PATH_MAX];
67         int ret;
68
69         if ((!res_name) || (!governor))
70                 return -EINVAL;
71
72         snprintf(path, PATH_MAX, "%s%s%s",
73                 DEVFREQ_GPU_PATH_PREFIX,
74                 res_name,
75                 DEVFREQ_GPU_CURR_GOVERNOR_PATH_SUFFIX);
76
77         ret = sysfs_write_str(path, governor);
78         if (ret < 0)
79                 return ret;
80
81         return 0;
82 }
83
84 static int tm2_dvfs_get_curr_freq(char *res_name)
85 {
86         char path[PATH_MAX];
87         int freq, ret;
88
89         if (!res_name)
90                 return -EINVAL;
91
92         snprintf(path, PATH_MAX, "%s%s%s",
93                 DEVFREQ_GPU_PATH_PREFIX,
94                 res_name,
95                 DEVFREQ_GPU_CURR_FREQ_PATH_SUFFIX);
96
97         ret = sysfs_read_int(path, &freq);
98         if (ret < 0)
99                 return ret;
100
101         return freq;
102 }
103
104 static int tm2_dvfs_get_min_freq(char *res_name)
105 {
106         char path[PATH_MAX];
107         int freq, ret;
108
109         if (!res_name)
110                 return -EINVAL;
111
112         snprintf(path, PATH_MAX, "%s%s%s",
113                 DEVFREQ_GPU_PATH_PREFIX,
114                 res_name,
115                 DEVFREQ_GPU_MIN_FREQ_PATH_SUFFIX);
116
117         ret = sysfs_read_int(path, &freq);
118         if (ret < 0)
119                 return ret;
120
121         return freq;
122 }
123
124 static int tm2_dvfs_set_min_freq(char *res_name, int freq)
125 {
126         char path[PATH_MAX];
127         int ret;
128
129         if ((!res_name) || (freq < 0))
130                 return -EINVAL;
131
132         snprintf(path, PATH_MAX, "%s%s%s",
133                 DEVFREQ_GPU_PATH_PREFIX,
134                 res_name,
135                 DEVFREQ_GPU_MIN_FREQ_PATH_SUFFIX);
136
137         ret = sysfs_write_int(path, freq);
138         if (ret < 0)
139                 return ret;
140
141         return 0;
142 }
143
144 static int tm2_dvfs_get_max_freq(char *res_name)
145 {
146         char path[PATH_MAX];
147         int freq, ret;
148
149         if (!res_name)
150                 return -EINVAL;
151
152         snprintf(path, PATH_MAX, "%s%s%s",
153                 DEVFREQ_GPU_PATH_PREFIX,
154                 res_name,
155                 DEVFREQ_GPU_MAX_FREQ_PATH_SUFFIX);
156
157         ret = sysfs_read_int(path, &freq);
158         if (ret < 0)
159                 return ret;
160
161         return freq;
162 }
163
164 static int tm2_dvfs_set_max_freq(char *res_name, int freq)
165 {
166         char path[PATH_MAX];
167         int ret;
168
169         if ((!res_name) || (freq < 0))
170                 return -EINVAL;
171
172         snprintf(path, PATH_MAX, "%s%s%s",
173                 DEVFREQ_GPU_PATH_PREFIX,
174                 res_name,
175                 DEVFREQ_GPU_MAX_FREQ_PATH_SUFFIX);
176
177         ret = sysfs_write_int(path, freq);
178         if (ret < 0)
179                 return ret;
180         return 0;
181 }
182
183
184 static struct pass_resource_dvfs_ops tm2_gpu_dvfs_ops =  {
185         .get_curr_governor = tm2_dvfs_get_curr_governor,
186         .set_curr_governor = tm2_dvfs_set_curr_governor,
187         .get_avail_governor = NULL,
188         .get_curr_freq = tm2_dvfs_get_curr_freq,
189         .get_min_freq = tm2_dvfs_get_min_freq,
190         .set_min_freq = tm2_dvfs_set_min_freq,
191         .get_max_freq = tm2_dvfs_get_max_freq,
192         .set_max_freq = tm2_dvfs_set_max_freq,
193         .get_up_threshold = NULL,
194         .set_up_threshold = NULL,
195         .get_load_table = NULL,
196 };
197
198 static int tm2_tmu_get_temp(char *res_name)
199 {
200         char path[PATH_MAX];
201         int temp;
202         int ret;
203
204         if (!res_name)
205                 return -EINVAL;
206
207         snprintf(path, PATH_MAX, "%s%d%s",
208                 TMU_PATH_PREFIX,
209                 TM2_GPU_THERMAL_ZONE_NUM,
210                 TMU_TEMP_PATH_SUFFIX);
211
212         ret = sysfs_read_int(path, &temp);
213         if (ret < 0)
214                 return ret;
215
216         return temp;
217 }
218
219 static int tm2_tmu_get_policy(char *res_name, char *policy)
220 {
221         char path[PATH_MAX];
222         int ret;
223
224         if ((!res_name) || (!policy))
225                 return -EINVAL;
226
227         snprintf(path, PATH_MAX, "%s%d%s",
228                 TMU_PATH_PREFIX,
229                 TM2_GPU_THERMAL_ZONE_NUM,
230                 TMU_POLICY_PATH_SUFFIX);
231
232         ret = sysfs_read_str(path, policy, BUFF_MAX);
233         if (ret < 0)
234                 return ret;
235
236         return 0;
237 }
238
239 static struct pass_resource_tmu_ops tm2_gpu_tmu_ops = {
240         .get_temp = tm2_tmu_get_temp,
241         .get_policy = tm2_tmu_get_policy,
242 };
243
244 static int tm2_gpu_open(char *res_name, struct pass_resource_info *info,
245                 struct pass_resource_common **common)
246 {
247         struct pass_resource_gpu *gpu_res;
248
249         if (!info)
250                 return -EINVAL;
251
252         /* TODO: Possibility of a memory leak */
253         gpu_res = calloc(1, sizeof(struct pass_resource_gpu));
254         if (!gpu_res)
255                 return -ENOMEM;
256
257         gpu_res->common.info = info;
258         gpu_res->dvfs = tm2_gpu_dvfs_ops;
259         gpu_res->tmu = tm2_gpu_tmu_ops;
260
261         *common = (struct pass_resource_common *) gpu_res;
262
263         return 0;
264 }
265
266 static int tm2_gpu_close(char *res_name, struct pass_resource_common *common)
267 {
268         if (!common)
269                 return -EINVAL;
270
271         free(common);
272
273         return 0;
274 }
275
276 HAL_MODULE_STRUCTURE = {
277         .magic = HAL_INFO_TAG,
278         .hal_version = HAL_VERSION,
279         .device_version = DEV_VERSION_GPU,
280         .id = PASS_RESOURCE_GPU_ID,
281         .name = PASS_RESOURCE_GPU_NAME,
282         .author = "Wook Song <wook16.song@samsung.com>",
283         .open = tm2_gpu_open,
284         .close = tm2_gpu_close,
285 };