0d9bf313a3f5a6534d025f0bc5ffd2b5cfdd1a61
[platform/core/system/pass.git] / src / resource / resource-gpu.c
1 /*
2  * PASS (Power Aware System Service) - GPU Resource Driver
3  *
4  * Copyright (c) 2021 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
19 /**
20  * @file        resource-gpu.c
21  * @brief       TBD
22  * @ingroup     TBD
23  */
24
25 #include <glib.h>
26
27 #include <hal/hal-power.h>
28
29 #include <util/common.h>
30 #include <util/devices.h>
31 #include <util/log.h>
32
33 #include <libsyscommon/resource-manager.h>
34 #include <libsyscommon/resource-type.h>
35 #include <libsyscommon/resource-device.h>
36
37 #include <resource-monitor/resource-monitor.h>
38
39 struct gpu_context {
40         char *device_name;
41         int index;
42 };
43
44 static int gpu_get_value_from_hal_power(struct syscommon_resman_resource *res,
45                                 const struct syscommon_resman_resource_attribute *attr,
46                                 void *data)
47 {
48         struct gpu_context *ctx;
49         int type;
50         int *val = (int *)data;
51         int _val;
52
53         if (!res || !attr || !data)
54                 return -EINVAL;
55
56         ctx = syscommon_resman_get_resource_privdata(res);
57         if (!ctx)
58                 return -EINVAL;
59
60         if (!ctx->device_name) {
61                 _E("%s: GPU_CTRL_DEVICE_ID is not yet initialized\n",
62                                 syscommon_resman_get_resource_name(res));
63                 return -EINVAL;
64         }
65
66         type = syscommon_resman_get_resource_type(res);
67
68         switch (attr->id) {
69         case GPU_ATTR_CUR_FREQ:
70                 _val = hal_power_dvfs_get_curr_freq(type, ctx->device_name);
71                 break;
72         case GPU_ATTR_MIN_FREQ:
73                 _val = hal_power_dvfs_get_min_freq(type, ctx->device_name);
74                 break;
75         case GPU_ATTR_MAX_FREQ:
76                 _val = hal_power_dvfs_get_max_freq(type, ctx->device_name);
77                 break;
78         case GPU_ATTR_AVAILABLE_MIN_FREQ:
79                 _val = hal_power_dvfs_get_available_min_freq(type, ctx->device_name);
80                 break;
81         case GPU_ATTR_AVAILABLE_MAX_FREQ:
82                 _val = hal_power_dvfs_get_available_max_freq(type, ctx->device_name);
83                 break;
84         default:
85                 return -EINVAL;
86         }
87
88         if (_val < 0)
89                 return -EINVAL;
90
91         *val = _val;
92
93         return 0;
94 }
95
96 static int gpu_get_string_value(struct syscommon_resman_resource *res,
97                                 const struct syscommon_resman_resource_attribute *attr,
98                                 void *data)
99 {
100         struct gpu_context *ctx;
101         char *buf = (char *)data;
102         int val;
103
104         if (!res || !attr || !data)
105                 return -EINVAL;
106
107         ctx = syscommon_resman_get_resource_privdata(res);
108         if (!ctx)
109                 return -EINVAL;
110
111         if (!ctx->device_name) {
112                 _E("%s: GPU_CTRL_DEVICE_ID is not yet initialized\n",
113                                 syscommon_resman_get_resource_name(res));
114                 return -EINVAL;
115         }
116
117         switch (attr->id) {
118         case GPU_ATTR_CUR_GOVERNOR:
119                 val = hal_power_dvfs_get_curr_governor(syscommon_resman_get_resource_type(res),
120                                                         ctx->device_name, buf);
121                 if (val < 0)
122                         return -EINVAL;
123                 break;
124         case GPU_ATTR_NAME:
125                 strncpy(buf, ctx->device_name, BUFF_MAX);
126                 break;
127         }
128
129         return 0;
130 }
131
132 static const struct syscommon_resman_resource_attribute gpu_attrs[] = {
133         {
134                 .name   = "GPU_ATTR_CUR_FREQ",
135                 .id     = GPU_ATTR_CUR_FREQ,
136                 .type   = SYSCOMMON_RESMAN_DATA_TYPE_INT,
137                 .flag   = SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC,
138                 .ops    = {
139                         .get = gpu_get_value_from_hal_power,
140                 },
141         }, {
142                 .name   = "GPU_ATTR_MIN_FREQ",
143                 .id     = GPU_ATTR_MIN_FREQ,
144                 .type   = SYSCOMMON_RESMAN_DATA_TYPE_INT,
145                 .flag   = SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC,
146                 .ops    = {
147                         .get = gpu_get_value_from_hal_power,
148                 },
149         }, {
150                 .name   = "GPU_ATTR_MAX_FREQ",
151                 .id     = GPU_ATTR_MAX_FREQ,
152                 .type   = SYSCOMMON_RESMAN_DATA_TYPE_INT,
153                 .flag   = SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC,
154                 .ops    = {
155                         .get = gpu_get_value_from_hal_power,
156                 }
157         }, {
158                 .name   = "GPU_ATTR_AVAILABLE_MIN_FREQ",
159                 .id     = GPU_ATTR_AVAILABLE_MIN_FREQ,
160                 .type   = SYSCOMMON_RESMAN_DATA_TYPE_INT,
161                 .flag   = SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC,
162                 .ops    = {
163                         .get = gpu_get_value_from_hal_power,
164                 }
165         }, {
166                 .name   = "GPU_ATTR_AVAILABLE_MAX_FREQ",
167                 .id     = GPU_ATTR_AVAILABLE_MAX_FREQ,
168                 .type   = SYSCOMMON_RESMAN_DATA_TYPE_INT,
169                 .flag   = SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC,
170                 .ops    = {
171                         .get = gpu_get_value_from_hal_power,
172                 }
173         }, {
174                 .name   = "GPU_ATTR_CUR_GOVERNOR",
175                 .id     = GPU_ATTR_CUR_GOVERNOR,
176                 .type   = SYSCOMMON_RESMAN_DATA_TYPE_STRING,
177                 .flag   = SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC,
178                 .ops    = {
179                         .get = gpu_get_string_value,
180                 }
181         }, {
182                 .name   = "GPU_ATTR_NAME",
183                 .id     = GPU_ATTR_NAME,
184                 .type   = SYSCOMMON_RESMAN_DATA_TYPE_STRING,
185                 .flag   = SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC,
186                 .ops    = {
187                         .get = gpu_get_string_value,
188                 }
189         },
190 };
191
192 static int gpu_setup_device_id(struct syscommon_resman_resource *res,
193                                 const struct syscommon_resman_resource_control *ctrl,
194                                 const void *data)
195 {
196         struct gpu_context *ctx;
197         const struct syscommon_resman_resource_device *device;
198         int resource_index = (int)(intptr_t)data;
199
200         if (!res || !ctrl)
201                 return -EINVAL;
202
203         ctx = syscommon_resman_get_resource_privdata(res);
204         if (!ctx)
205                 return -EINVAL;
206
207         device = syscommon_resman_find_resource_device(syscommon_resman_get_resource_type(res), resource_index);
208         if (!device) {
209                 _E("Not available resource: type: %s, index: %d\n",
210                                 syscommon_resman_get_resource_name(res), resource_index);
211                 return -EINVAL;
212         }
213
214         if (ctx->device_name)
215                 free(ctx->device_name);
216
217         ctx->device_name = g_strdup(device->name);
218         ctx->index = resource_index;
219
220         return 0;
221 }
222
223 static const struct syscommon_resman_resource_control gpu_ctrls[] = {
224         {
225                 .name = "GPU_CTRL_DEVICE_ID",
226                 .id = GPU_CTRL_DEVICE_ID,
227                 .ops = {
228                         .set = gpu_setup_device_id,
229                 },
230         },
231 };
232
233 static int gpu_create(struct syscommon_resman_resource *res)
234 {
235         struct gpu_context *ctx;
236
237         ctx = calloc(1, sizeof(struct gpu_context));
238         if (!ctx)
239                 return -ENOMEM;
240
241         syscommon_resman_set_resource_privdata(res, ctx);
242
243         return 0;
244 }
245
246 static void gpu_delete(struct syscommon_resman_resource *res)
247 {
248         struct gpu_context *ctx;
249
250         if (!res)
251                 return;
252
253         ctx = syscommon_resman_get_resource_privdata(res);
254         if (!ctx)
255                 return;
256
257         if (ctx->device_name) {
258                 free(ctx->device_name);
259                 ctx->device_name = NULL;
260         }
261         free(ctx);
262         syscommon_resman_set_resource_privdata(res, NULL);
263 }
264
265 static const struct syscommon_resman_resource_driver gpu_resource_driver = {
266         .name           = "GPU",
267         .type           = RESOURCE_TYPE_GPU,
268         .attrs          = gpu_attrs,
269         .num_attrs      = ARRAY_SIZE(gpu_attrs),
270         .ctrls          = gpu_ctrls,
271         .num_ctrls      = ARRAY_SIZE(gpu_ctrls),
272         .ops            = {
273                 .create = gpu_create,
274                 .delete = gpu_delete,
275         },
276 };
277 SYSCOMMON_RESMAN_RESOURCE_DRIVER_REGISTER(&gpu_resource_driver)