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