nomali_api.cc revision 10915:71ace17ccb3d
1/*
2 * Copyright (c) 2014-2015 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);
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    {
79        BaseGpu::reset();
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
208
209
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
356