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