/*
 * Copyright (c) 2014-2016 ARM Limited
 * All rights reserved
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Authors: Andreas Sandberg
 */

#include "libnomali/nomali.h"

#include <cstring>

#include "mali_t6xx.hh"
#include "mali_t7xx.hh"

#define EXPORT __attribute__ ((visibility ("default")))

static const char *errstrs[] = {
    "No error",
    "Unknown error",
    "Memory allocation failed",
    "Invalid model handle",
    "Invalid parameter",
};

static_assert(sizeof(errstrs) / sizeof(*errstrs) == NOMALI_E_NUM_ERRORS,
              "NoMali API error descriptions out of sync!");

class NoMaliApi
{
  public:
    NoMaliApi();
    ~NoMaliApi();

    void setGpu(NoMali::GPU *gpu) { _gpu = gpu; }

  public:
    nomali_error_t setCallback(const nomali_callback_t *callback);

    nomali_error_t getInfo(nomali_info_t *info);

    nomali_error_t reset();
    nomali_error_t regRead(uint32_t *value, nomali_addr_t addr);
    nomali_error_t regWrite(nomali_addr_t addr, uint32_t value);
    nomali_error_t regReadRaw(uint32_t *value, nomali_addr_t addr);
    nomali_error_t regWriteRaw(nomali_addr_t addr, uint32_t value);
    nomali_error_t intState(int *state, nomali_int_t intno) const;

  public:
    void callbackInt(nomali_int_t intno, int set);
    void callbackReset();

  private:
    nomali_callback_t callbacks[NOMALI_CALLBACK_NUM_CALLBACKS];

    NoMali::GPU *_gpu;
};

template<class BaseGpu>
class NoMaliApiGpu
    : public BaseGpu
{
  public:
    template<typename... Args>
    NoMaliApiGpu(NoMaliApi &_api, Args &&... args)
        : BaseGpu(std::forward<Args>(args)...),
          api(_api)
    {
        reset();
    }

    void reset() override {
        BaseGpu::reset();
        api.callbackReset();
    }

  public:
    void intJob(int set) override { api.callbackInt(NOMALI_INT_JOB, set); }
    void intMMU(int set) override { api.callbackInt(NOMALI_INT_MMU, set); }
    void intGPU(int set) override { api.callbackInt(NOMALI_INT_GPU, set); }

  private:
    NoMaliApi &api;
};


NoMaliApi::NoMaliApi()
    : _gpu(nullptr)
{
    memset(callbacks, 0, sizeof(callbacks));
}


NoMaliApi::~NoMaliApi()
{
}

nomali_error_t
NoMaliApi::setCallback(const nomali_callback_t *callback)
{
    if (!callback ||
        callback->type >= NOMALI_CALLBACK_NUM_CALLBACKS)
        return NOMALI_E_INVALID;

    callbacks[callback->type] = *callback;

    return NOMALI_E_OK;
}

nomali_error_t
NoMaliApi::getInfo(nomali_info_t *info)
{
    if (!info)
        return NOMALI_E_INVALID;

    info->reg_size = 0x4000;

    return NOMALI_E_OK;
}

nomali_error_t
NoMaliApi::reset()
{
    _gpu->reset();
    return NOMALI_E_OK;
}

nomali_error_t
NoMaliApi::regRead(uint32_t *value, nomali_addr_t addr)
{
    if (!value)
        return NOMALI_E_INVALID;

    *value = _gpu->readReg(NoMali::RegAddr(addr));

    return NOMALI_E_OK;
}

nomali_error_t
NoMaliApi::regWrite(nomali_addr_t addr, uint32_t value)
{
    _gpu->writeReg(NoMali::RegAddr(addr), value);

    return NOMALI_E_OK;
}


nomali_error_t
NoMaliApi::regReadRaw(uint32_t *value, nomali_addr_t addr)
{
    if (!value)
        return NOMALI_E_INVALID;

    *value = _gpu->readRegRaw(NoMali::RegAddr(addr));

    return NOMALI_E_OK;
}

nomali_error_t
NoMaliApi::regWriteRaw(nomali_addr_t addr, uint32_t value)
{
    _gpu->writeRegRaw(NoMali::RegAddr(addr), value);

    return NOMALI_E_OK;
}

nomali_error_t
NoMaliApi::intState(int *state, nomali_int_t intno) const
{
    if (!state)
        return NOMALI_E_INVALID;

    switch (intno) {
      case NOMALI_INT_GPU:
        *state = _gpu->intGPUAsserted();
        break;

      case NOMALI_INT_JOB:
        *state = _gpu->intJobAsserted();
        break;

      case NOMALI_INT_MMU:
        *state = _gpu->intMMUAsserted();
        break;

      default:
        return NOMALI_E_INVALID;
    }

    return NOMALI_E_OK;
}


void
NoMaliApi::callbackInt(nomali_int_t intno, int set)
{
    const nomali_callback_t &c(callbacks[NOMALI_CALLBACK_INT]);

    if (c.func.interrupt)
        c.func.interrupt(static_cast<nomali_handle_t>(this), c.usr, intno, set);
}

void
NoMaliApi::callbackReset()
{
    const nomali_callback_t &c(callbacks[NOMALI_CALLBACK_RESET]);

    if (c.func.reset)
        c.func.reset(static_cast<nomali_handle_t>(this), c.usr);
}



static NoMaliApi *
get_gpu(nomali_handle_t h)
{
    return h ? static_cast<NoMaliApi *>(h) : nullptr;
}


extern "C" EXPORT nomali_api_version_t
nomali_api_version()
{
    return NOMALI_API_VERSION;
}

extern "C" EXPORT nomali_error_t
nomali_create(nomali_handle_t *h, const nomali_config_t *cfg)
{
    if (h && cfg) {
        NoMaliApi *api(new NoMaliApi());
        *h = api;
        if (!h)
            return NOMALI_E_MEMORY;

        NoMali::GPU *gpu;
        switch (cfg->type) {
          case NOMALI_GPU_T60X:
            gpu = new NoMaliApiGpu<NoMali::MaliT60x>(
                *api,
                cfg->ver_maj, cfg->ver_min, cfg->ver_status);
            break;

          case NOMALI_GPU_T62X:
            gpu = new NoMaliApiGpu<NoMali::MaliT62x>(
                *api,
                cfg->ver_maj, cfg->ver_min, cfg->ver_status);
            break;


          case NOMALI_GPU_T76X:
            gpu = new NoMaliApiGpu<NoMali::MaliT76x>(
                *api,
                cfg->ver_maj, cfg->ver_min, cfg->ver_status);
            break;

          default:
            delete api;
            return NOMALI_E_INVALID;
        };

        if (!gpu) {
            delete api;
            return NOMALI_E_MEMORY;
        }

        api->setGpu(gpu);

        return NOMALI_E_OK;
    } else {
        return NOMALI_E_INVALID;
    }
}

extern "C" EXPORT nomali_error_t
nomali_destroy(nomali_handle_t h)
{
    NoMaliApi *gpu(get_gpu(h));

    if (gpu) {
        delete gpu;
        return NOMALI_E_OK;
    } else {
        return NOMALI_E_HANDLE;
    }
}

extern "C" EXPORT const char *
nomali_errstr(nomali_error_t error)
{
    if (error < NOMALI_E_NUM_ERRORS)
        return errstrs[error];
    else
        return "Invalid error number";
}

extern "C" EXPORT nomali_error_t
nomali_set_callback(nomali_handle_t h,
                    const nomali_callback_t *callback)
{
    NoMaliApi *gpu(get_gpu(h));
    return gpu ? gpu->setCallback(callback) : NOMALI_E_HANDLE;
}

extern "C" EXPORT nomali_error_t
nomali_get_info(nomali_handle_t h, nomali_info_t *info)
{
    NoMaliApi *gpu(get_gpu(h));
    return gpu ? gpu->getInfo(info) : NOMALI_E_HANDLE;
}

extern "C" EXPORT nomali_error_t
nomali_reset(nomali_handle_t h)
{
    NoMaliApi *gpu(get_gpu(h));
    return gpu ? gpu->reset() : NOMALI_E_HANDLE;
}

extern "C" EXPORT nomali_error_t
nomali_reg_read(nomali_handle_t h, uint32_t *value,
                nomali_addr_t addr)
{
    NoMaliApi *gpu(get_gpu(h));
    return gpu ? gpu->regRead(value, addr) : NOMALI_E_HANDLE;
}

extern "C" EXPORT nomali_error_t
nomali_reg_write(nomali_handle_t h,
                 nomali_addr_t addr, uint32_t value)
{
    NoMaliApi *gpu(get_gpu(h));
    return gpu ? gpu->regWrite(addr, value) : NOMALI_E_HANDLE;
}


extern "C" EXPORT nomali_error_t
nomali_reg_read_raw(nomali_handle_t h, uint32_t *value,
                    nomali_addr_t addr)
{
    NoMaliApi *gpu(get_gpu(h));
    return gpu ? gpu->regReadRaw(value, addr) : NOMALI_E_HANDLE;
}

extern "C" EXPORT nomali_error_t
nomali_reg_write_raw(nomali_handle_t h,
                     nomali_addr_t addr, uint32_t value)
{
    NoMaliApi *gpu(get_gpu(h));
    return gpu ? gpu->regWriteRaw(addr, value) : NOMALI_E_HANDLE;
}

extern "C" EXPORT nomali_error_t
nomali_int_state(nomali_handle_t h, int *state,
                 nomali_int_t intno)
{
    NoMaliApi *gpu(get_gpu(h));
    return gpu ? gpu->intState(state, intno) : NOMALI_E_HANDLE;
}

