/*
 * Copyright (c) 2014-2015 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 <inttypes.h>

#include "nomali_test_helpers.h"
#include "../lib/mali_midg_regmap.h"

static void
on_int(nomali_handle_t h, void *usr, nomali_int_t intno, int set)
{
    test_diag("on_int: intno: %i, set: %i", intno, set);
    *(int*)usr = !!set;
}

static void
test_gpu_int(nomali_handle_t h)
{
    nomali_error_t error = NOMALI_E_OK;
    int int_triggered = 0;
    nomali_callback_t int_callback = {
        .type = NOMALI_CALLBACK_INT,
        .usr = &int_triggered,
        .func.interrupt = on_int,
    };

    nomali_callback_t int_null_callback = {
        .type = NOMALI_CALLBACK_INT,
        .usr = NULL,
        .func.interrupt = NULL,
    };

    /*
     * Raise an interrupt without callbacks
     */
    E_NOMALI_BAIL(nomali_reg_write(h,
                                   GPU_CONTROL_REG(GPU_IRQ_CLEAR),
                                   GPU_IRQ_REG_ALL));

    E_NOMALI_BAIL(nomali_reg_write(h, GPU_CONTROL_REG(GPU_IRQ_MASK),
                                   GPU_FAULT));

    E_NOMALI_BAIL(nomali_reg_write(h, GPU_CONTROL_REG(GPU_IRQ_RAWSTAT),
                                   GPU_FAULT));

    E_NOMALI_BAIL(nomali_reg_write(h,
                                   GPU_CONTROL_REG(GPU_IRQ_CLEAR),
                                   GPU_IRQ_REG_ALL));

    /*
     * Register callbacks and raise interrupt again.
     */
    E_NOMALI_BAIL(nomali_set_callback(h, &int_callback));
    if (int_triggered != 0) {
        test_diag("Got spurious interrupt\n");
        test_fail("gpu_int");
    }

    E_NOMALI_BAIL(nomali_reg_write(h, GPU_CONTROL_REG(GPU_IRQ_RAWSTAT),
                                   GPU_FAULT));
    if (int_triggered == 1) {
        test_ok("gpu_int");
    } else {
        test_fail("gpu_int");
    }
    int_triggered = 0;


    /*
     * Register mask interrupts and raise interrupt again.
     */
    E_NOMALI_BAIL(nomali_reg_write(h,
                                   GPU_CONTROL_REG(GPU_IRQ_CLEAR),
                                   GPU_IRQ_REG_ALL));
    E_NOMALI_BAIL(nomali_reg_write(h, GPU_CONTROL_REG(GPU_IRQ_MASK),
                                   0));
    E_NOMALI_BAIL(nomali_reg_write(h, GPU_CONTROL_REG(GPU_IRQ_RAWSTAT),
                                   GPU_FAULT));
    if (int_triggered == 0) {
        test_ok("gpu_int_masked");
    } else {
        test_fail("gpu_int_maked");
    }
    E_NOMALI_BAIL(nomali_reg_write(h,
                                   GPU_CONTROL_REG(GPU_IRQ_CLEAR),
                                   GPU_IRQ_REG_ALL));
    E_NOMALI_BAIL(nomali_set_callback(h, &int_null_callback));
}

int
main(int argc, char **argv)
{
    const nomali_config_t cfg = {
        .type = NOMALI_GPU_T60X,
        .ver_maj = 0,
        .ver_min = 1,
        .ver_status = 0,
    };

    nomali_handle_t h;
    nomali_error_t error = NOMALI_E_OK;

    E_NOMALI_BAIL(nomali_create(&h, &cfg));

    test_gpu_int(h);

    E_NOMALI_BAIL(nomali_destroy(h));

    return 0;
}
