nomali_api.cc (10915:71ace17ccb3d) nomali_api.cc (11313:89fd4a775287)
1/*
1/*
2 * Copyright (c) 2014-2015 ARM Limited
2 * Copyright (c) 2014-2016 ARM Limited
3 * All rights reserved
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * Authors: Andreas Sandberg
18 */
19
20#include "libnomali/nomali.h"
21
22#include <cstring>
23
24#include "mali_t6xx.hh"
25#include "mali_t7xx.hh"
26
27#define EXPORT __attribute__ ((visibility ("default")))
28
29static const char *errstrs[] = {
30 "No error",
31 "Unknown error",
32 "Memory allocation failed",
33 "Invalid model handle",
34 "Invalid parameter",
35};
36
37static_assert(sizeof(errstrs) / sizeof(*errstrs) == NOMALI_E_NUM_ERRORS,
38 "NoMali API error descriptions out of sync!");
39
40class NoMaliApi
41{
42 public:
43 NoMaliApi();
44 ~NoMaliApi();
45
46 void setGpu(NoMali::GPU *gpu) { _gpu = gpu; }
47
48 public:
49 nomali_error_t setCallback(const nomali_callback_t *callback);
50
51 nomali_error_t getInfo(nomali_info_t *info);
52
53 nomali_error_t reset();
54 nomali_error_t regRead(uint32_t *value, nomali_addr_t addr);
55 nomali_error_t regWrite(nomali_addr_t addr, uint32_t value);
56 nomali_error_t regReadRaw(uint32_t *value, nomali_addr_t addr);
57 nomali_error_t regWriteRaw(nomali_addr_t addr, uint32_t value);
58 nomali_error_t intState(int *state, nomali_int_t intno) const;
59
60 public:
61 void callbackInt(nomali_int_t intno, int set);
3 * All rights reserved
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * Authors: Andreas Sandberg
18 */
19
20#include "libnomali/nomali.h"
21
22#include <cstring>
23
24#include "mali_t6xx.hh"
25#include "mali_t7xx.hh"
26
27#define EXPORT __attribute__ ((visibility ("default")))
28
29static const char *errstrs[] = {
30 "No error",
31 "Unknown error",
32 "Memory allocation failed",
33 "Invalid model handle",
34 "Invalid parameter",
35};
36
37static_assert(sizeof(errstrs) / sizeof(*errstrs) == NOMALI_E_NUM_ERRORS,
38 "NoMali API error descriptions out of sync!");
39
40class NoMaliApi
41{
42 public:
43 NoMaliApi();
44 ~NoMaliApi();
45
46 void setGpu(NoMali::GPU *gpu) { _gpu = gpu; }
47
48 public:
49 nomali_error_t setCallback(const nomali_callback_t *callback);
50
51 nomali_error_t getInfo(nomali_info_t *info);
52
53 nomali_error_t reset();
54 nomali_error_t regRead(uint32_t *value, nomali_addr_t addr);
55 nomali_error_t regWrite(nomali_addr_t addr, uint32_t value);
56 nomali_error_t regReadRaw(uint32_t *value, nomali_addr_t addr);
57 nomali_error_t regWriteRaw(nomali_addr_t addr, uint32_t value);
58 nomali_error_t intState(int *state, nomali_int_t intno) const;
59
60 public:
61 void callbackInt(nomali_int_t intno, int set);
62 void callbackReset();
62
63 private:
64 nomali_callback_t callbacks[NOMALI_CALLBACK_NUM_CALLBACKS];
65
66 NoMali::GPU *_gpu;
67};
68
69template<class BaseGpu>
70class NoMaliApiGpu
71 : public BaseGpu
72{
73 public:
74 template<typename... Args>
75 NoMaliApiGpu(NoMaliApi &_api, Args &&... args)
76 : BaseGpu(std::forward<Args>(args)...),
77 api(_api)
78 {
63
64 private:
65 nomali_callback_t callbacks[NOMALI_CALLBACK_NUM_CALLBACKS];
66
67 NoMali::GPU *_gpu;
68};
69
70template<class BaseGpu>
71class NoMaliApiGpu
72 : public BaseGpu
73{
74 public:
75 template<typename... Args>
76 NoMaliApiGpu(NoMaliApi &_api, Args &&... args)
77 : BaseGpu(std::forward<Args>(args)...),
78 api(_api)
79 {
80 reset();
81 }
82
83 void reset() override {
79 BaseGpu::reset();
84 BaseGpu::reset();
85 api.callbackReset();
80 }
81
82 public:
83 void intJob(int set) override { api.callbackInt(NOMALI_INT_JOB, set); }
84 void intMMU(int set) override { api.callbackInt(NOMALI_INT_MMU, set); }
85 void intGPU(int set) override { api.callbackInt(NOMALI_INT_GPU, set); }
86
87 private:
88 NoMaliApi &api;
89};
90
91
92NoMaliApi::NoMaliApi()
93 : _gpu(nullptr)
94{
95 memset(callbacks, 0, sizeof(callbacks));
96}
97
98
99NoMaliApi::~NoMaliApi()
100{
101}
102
103nomali_error_t
104NoMaliApi::setCallback(const nomali_callback_t *callback)
105{
106 if (!callback ||
107 callback->type >= NOMALI_CALLBACK_NUM_CALLBACKS)
108 return NOMALI_E_INVALID;
109
110 callbacks[callback->type] = *callback;
111
112 return NOMALI_E_OK;
113}
114
115nomali_error_t
116NoMaliApi::getInfo(nomali_info_t *info)
117{
118 if (!info)
119 return NOMALI_E_INVALID;
120
121 info->reg_size = 0x4000;
122
123 return NOMALI_E_OK;
124}
125
126nomali_error_t
127NoMaliApi::reset()
128{
129 _gpu->reset();
130 return NOMALI_E_OK;
131}
132
133nomali_error_t
134NoMaliApi::regRead(uint32_t *value, nomali_addr_t addr)
135{
136 if (!value)
137 return NOMALI_E_INVALID;
138
139 *value = _gpu->readReg(NoMali::RegAddr(addr));
140
141 return NOMALI_E_OK;
142}
143
144nomali_error_t
145NoMaliApi::regWrite(nomali_addr_t addr, uint32_t value)
146{
147 _gpu->writeReg(NoMali::RegAddr(addr), value);
148
149 return NOMALI_E_OK;
150}
151
152
153nomali_error_t
154NoMaliApi::regReadRaw(uint32_t *value, nomali_addr_t addr)
155{
156 if (!value)
157 return NOMALI_E_INVALID;
158
159 *value = _gpu->readRegRaw(NoMali::RegAddr(addr));
160
161 return NOMALI_E_OK;
162}
163
164nomali_error_t
165NoMaliApi::regWriteRaw(nomali_addr_t addr, uint32_t value)
166{
167 _gpu->writeRegRaw(NoMali::RegAddr(addr), value);
168
169 return NOMALI_E_OK;
170}
171
172nomali_error_t
173NoMaliApi::intState(int *state, nomali_int_t intno) const
174{
175 if (!state)
176 return NOMALI_E_INVALID;
177
178 switch (intno) {
179 case NOMALI_INT_GPU:
180 *state = _gpu->intGPUAsserted();
181 break;
182
183 case NOMALI_INT_JOB:
184 *state = _gpu->intJobAsserted();
185 break;
186
187 case NOMALI_INT_MMU:
188 *state = _gpu->intMMUAsserted();
189 break;
190
191 default:
192 return NOMALI_E_INVALID;
193 }
194
195 return NOMALI_E_OK;
196}
197
198
199void
200NoMaliApi::callbackInt(nomali_int_t intno, int set)
201{
202 const nomali_callback_t &c(callbacks[NOMALI_CALLBACK_INT]);
203
204 if (c.func.interrupt)
205 c.func.interrupt(static_cast<nomali_handle_t>(this), c.usr, intno, set);
206}
207
86 }
87
88 public:
89 void intJob(int set) override { api.callbackInt(NOMALI_INT_JOB, set); }
90 void intMMU(int set) override { api.callbackInt(NOMALI_INT_MMU, set); }
91 void intGPU(int set) override { api.callbackInt(NOMALI_INT_GPU, set); }
92
93 private:
94 NoMaliApi &api;
95};
96
97
98NoMaliApi::NoMaliApi()
99 : _gpu(nullptr)
100{
101 memset(callbacks, 0, sizeof(callbacks));
102}
103
104
105NoMaliApi::~NoMaliApi()
106{
107}
108
109nomali_error_t
110NoMaliApi::setCallback(const nomali_callback_t *callback)
111{
112 if (!callback ||
113 callback->type >= NOMALI_CALLBACK_NUM_CALLBACKS)
114 return NOMALI_E_INVALID;
115
116 callbacks[callback->type] = *callback;
117
118 return NOMALI_E_OK;
119}
120
121nomali_error_t
122NoMaliApi::getInfo(nomali_info_t *info)
123{
124 if (!info)
125 return NOMALI_E_INVALID;
126
127 info->reg_size = 0x4000;
128
129 return NOMALI_E_OK;
130}
131
132nomali_error_t
133NoMaliApi::reset()
134{
135 _gpu->reset();
136 return NOMALI_E_OK;
137}
138
139nomali_error_t
140NoMaliApi::regRead(uint32_t *value, nomali_addr_t addr)
141{
142 if (!value)
143 return NOMALI_E_INVALID;
144
145 *value = _gpu->readReg(NoMali::RegAddr(addr));
146
147 return NOMALI_E_OK;
148}
149
150nomali_error_t
151NoMaliApi::regWrite(nomali_addr_t addr, uint32_t value)
152{
153 _gpu->writeReg(NoMali::RegAddr(addr), value);
154
155 return NOMALI_E_OK;
156}
157
158
159nomali_error_t
160NoMaliApi::regReadRaw(uint32_t *value, nomali_addr_t addr)
161{
162 if (!value)
163 return NOMALI_E_INVALID;
164
165 *value = _gpu->readRegRaw(NoMali::RegAddr(addr));
166
167 return NOMALI_E_OK;
168}
169
170nomali_error_t
171NoMaliApi::regWriteRaw(nomali_addr_t addr, uint32_t value)
172{
173 _gpu->writeRegRaw(NoMali::RegAddr(addr), value);
174
175 return NOMALI_E_OK;
176}
177
178nomali_error_t
179NoMaliApi::intState(int *state, nomali_int_t intno) const
180{
181 if (!state)
182 return NOMALI_E_INVALID;
183
184 switch (intno) {
185 case NOMALI_INT_GPU:
186 *state = _gpu->intGPUAsserted();
187 break;
188
189 case NOMALI_INT_JOB:
190 *state = _gpu->intJobAsserted();
191 break;
192
193 case NOMALI_INT_MMU:
194 *state = _gpu->intMMUAsserted();
195 break;
196
197 default:
198 return NOMALI_E_INVALID;
199 }
200
201 return NOMALI_E_OK;
202}
203
204
205void
206NoMaliApi::callbackInt(nomali_int_t intno, int set)
207{
208 const nomali_callback_t &c(callbacks[NOMALI_CALLBACK_INT]);
209
210 if (c.func.interrupt)
211 c.func.interrupt(static_cast<nomali_handle_t>(this), c.usr, intno, set);
212}
213
214void
215NoMaliApi::callbackReset()
216{
217 const nomali_callback_t &c(callbacks[NOMALI_CALLBACK_RESET]);
208
218
219 if (c.func.reset)
220 c.func.reset(static_cast<nomali_handle_t>(this), c.usr);
221}
209
222
223
224
210static NoMaliApi *
211get_gpu(nomali_handle_t h)
212{
213 return h ? static_cast<NoMaliApi *>(h) : nullptr;
214}
215
216
217extern "C" EXPORT nomali_api_version_t
218nomali_api_version()
219{
220 return NOMALI_API_VERSION;
221}
222
223extern "C" EXPORT nomali_error_t
224nomali_create(nomali_handle_t *h, const nomali_config_t *cfg)
225{
226 if (h && cfg) {
227 NoMaliApi *api(new NoMaliApi());
228 *h = api;
229 if (!h)
230 return NOMALI_E_MEMORY;
231
232 NoMali::GPU *gpu;
233 switch (cfg->type) {
234 case NOMALI_GPU_T60X:
235 gpu = new NoMaliApiGpu<NoMali::MaliT60x>(
236 *api,
237 cfg->ver_maj, cfg->ver_min, cfg->ver_status);
238 break;
239
240 case NOMALI_GPU_T62X:
241 gpu = new NoMaliApiGpu<NoMali::MaliT62x>(
242 *api,
243 cfg->ver_maj, cfg->ver_min, cfg->ver_status);
244 break;
245
246
247 case NOMALI_GPU_T76X:
248 gpu = new NoMaliApiGpu<NoMali::MaliT76x>(
249 *api,
250 cfg->ver_maj, cfg->ver_min, cfg->ver_status);
251 break;
252
253 default:
254 delete api;
255 return NOMALI_E_INVALID;
256 };
257
258 if (!gpu) {
259 delete api;
260 return NOMALI_E_MEMORY;
261 }
262
263 api->setGpu(gpu);
264
265 return NOMALI_E_OK;
266 } else {
267 return NOMALI_E_INVALID;
268 }
269}
270
271extern "C" EXPORT nomali_error_t
272nomali_destroy(nomali_handle_t h)
273{
274 NoMaliApi *gpu(get_gpu(h));
275
276 if (gpu) {
277 delete gpu;
278 return NOMALI_E_OK;
279 } else {
280 return NOMALI_E_HANDLE;
281 }
282}
283
284extern "C" EXPORT const char *
285nomali_errstr(nomali_error_t error)
286{
287 if (error < NOMALI_E_NUM_ERRORS)
288 return errstrs[error];
289 else
290 return "Invalid error number";
291}
292
293extern "C" EXPORT nomali_error_t
294nomali_set_callback(nomali_handle_t h,
295 const nomali_callback_t *callback)
296{
297 NoMaliApi *gpu(get_gpu(h));
298 return gpu ? gpu->setCallback(callback) : NOMALI_E_HANDLE;
299}
300
301extern "C" EXPORT nomali_error_t
302nomali_get_info(nomali_handle_t h, nomali_info_t *info)
303{
304 NoMaliApi *gpu(get_gpu(h));
305 return gpu ? gpu->getInfo(info) : NOMALI_E_HANDLE;
306}
307
308extern "C" EXPORT nomali_error_t
309nomali_reset(nomali_handle_t h)
310{
311 NoMaliApi *gpu(get_gpu(h));
312 return gpu ? gpu->reset() : NOMALI_E_HANDLE;
313}
314
315extern "C" EXPORT nomali_error_t
316nomali_reg_read(nomali_handle_t h, uint32_t *value,
317 nomali_addr_t addr)
318{
319 NoMaliApi *gpu(get_gpu(h));
320 return gpu ? gpu->regRead(value, addr) : NOMALI_E_HANDLE;
321}
322
323extern "C" EXPORT nomali_error_t
324nomali_reg_write(nomali_handle_t h,
325 nomali_addr_t addr, uint32_t value)
326{
327 NoMaliApi *gpu(get_gpu(h));
328 return gpu ? gpu->regWrite(addr, value) : NOMALI_E_HANDLE;
329}
330
331
332extern "C" EXPORT nomali_error_t
333nomali_reg_read_raw(nomali_handle_t h, uint32_t *value,
334 nomali_addr_t addr)
335{
336 NoMaliApi *gpu(get_gpu(h));
337 return gpu ? gpu->regReadRaw(value, addr) : NOMALI_E_HANDLE;
338}
339
340extern "C" EXPORT nomali_error_t
341nomali_reg_write_raw(nomali_handle_t h,
342 nomali_addr_t addr, uint32_t value)
343{
344 NoMaliApi *gpu(get_gpu(h));
345 return gpu ? gpu->regWriteRaw(addr, value) : NOMALI_E_HANDLE;
346}
347
348extern "C" EXPORT nomali_error_t
349nomali_int_state(nomali_handle_t h, int *state,
350 nomali_int_t intno)
351{
352 NoMaliApi *gpu(get_gpu(h));
353 return gpu ? gpu->intState(state, intno) : NOMALI_E_HANDLE;
354}
355
225static NoMaliApi *
226get_gpu(nomali_handle_t h)
227{
228 return h ? static_cast<NoMaliApi *>(h) : nullptr;
229}
230
231
232extern "C" EXPORT nomali_api_version_t
233nomali_api_version()
234{
235 return NOMALI_API_VERSION;
236}
237
238extern "C" EXPORT nomali_error_t
239nomali_create(nomali_handle_t *h, const nomali_config_t *cfg)
240{
241 if (h && cfg) {
242 NoMaliApi *api(new NoMaliApi());
243 *h = api;
244 if (!h)
245 return NOMALI_E_MEMORY;
246
247 NoMali::GPU *gpu;
248 switch (cfg->type) {
249 case NOMALI_GPU_T60X:
250 gpu = new NoMaliApiGpu<NoMali::MaliT60x>(
251 *api,
252 cfg->ver_maj, cfg->ver_min, cfg->ver_status);
253 break;
254
255 case NOMALI_GPU_T62X:
256 gpu = new NoMaliApiGpu<NoMali::MaliT62x>(
257 *api,
258 cfg->ver_maj, cfg->ver_min, cfg->ver_status);
259 break;
260
261
262 case NOMALI_GPU_T76X:
263 gpu = new NoMaliApiGpu<NoMali::MaliT76x>(
264 *api,
265 cfg->ver_maj, cfg->ver_min, cfg->ver_status);
266 break;
267
268 default:
269 delete api;
270 return NOMALI_E_INVALID;
271 };
272
273 if (!gpu) {
274 delete api;
275 return NOMALI_E_MEMORY;
276 }
277
278 api->setGpu(gpu);
279
280 return NOMALI_E_OK;
281 } else {
282 return NOMALI_E_INVALID;
283 }
284}
285
286extern "C" EXPORT nomali_error_t
287nomali_destroy(nomali_handle_t h)
288{
289 NoMaliApi *gpu(get_gpu(h));
290
291 if (gpu) {
292 delete gpu;
293 return NOMALI_E_OK;
294 } else {
295 return NOMALI_E_HANDLE;
296 }
297}
298
299extern "C" EXPORT const char *
300nomali_errstr(nomali_error_t error)
301{
302 if (error < NOMALI_E_NUM_ERRORS)
303 return errstrs[error];
304 else
305 return "Invalid error number";
306}
307
308extern "C" EXPORT nomali_error_t
309nomali_set_callback(nomali_handle_t h,
310 const nomali_callback_t *callback)
311{
312 NoMaliApi *gpu(get_gpu(h));
313 return gpu ? gpu->setCallback(callback) : NOMALI_E_HANDLE;
314}
315
316extern "C" EXPORT nomali_error_t
317nomali_get_info(nomali_handle_t h, nomali_info_t *info)
318{
319 NoMaliApi *gpu(get_gpu(h));
320 return gpu ? gpu->getInfo(info) : NOMALI_E_HANDLE;
321}
322
323extern "C" EXPORT nomali_error_t
324nomali_reset(nomali_handle_t h)
325{
326 NoMaliApi *gpu(get_gpu(h));
327 return gpu ? gpu->reset() : NOMALI_E_HANDLE;
328}
329
330extern "C" EXPORT nomali_error_t
331nomali_reg_read(nomali_handle_t h, uint32_t *value,
332 nomali_addr_t addr)
333{
334 NoMaliApi *gpu(get_gpu(h));
335 return gpu ? gpu->regRead(value, addr) : NOMALI_E_HANDLE;
336}
337
338extern "C" EXPORT nomali_error_t
339nomali_reg_write(nomali_handle_t h,
340 nomali_addr_t addr, uint32_t value)
341{
342 NoMaliApi *gpu(get_gpu(h));
343 return gpu ? gpu->regWrite(addr, value) : NOMALI_E_HANDLE;
344}
345
346
347extern "C" EXPORT nomali_error_t
348nomali_reg_read_raw(nomali_handle_t h, uint32_t *value,
349 nomali_addr_t addr)
350{
351 NoMaliApi *gpu(get_gpu(h));
352 return gpu ? gpu->regReadRaw(value, addr) : NOMALI_E_HANDLE;
353}
354
355extern "C" EXPORT nomali_error_t
356nomali_reg_write_raw(nomali_handle_t h,
357 nomali_addr_t addr, uint32_t value)
358{
359 NoMaliApi *gpu(get_gpu(h));
360 return gpu ? gpu->regWriteRaw(addr, value) : NOMALI_E_HANDLE;
361}
362
363extern "C" EXPORT nomali_error_t
364nomali_int_state(nomali_handle_t h, int *state,
365 nomali_int_t intno)
366{
367 NoMaliApi *gpu(get_gpu(h));
368 return gpu ? gpu->intState(state, intno) : NOMALI_E_HANDLE;
369}
370