/**
 * Copyright (C) ARM Limited 2010-2016. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include "gator.h"

#include <linux/module.h>
#include <linux/time.h>
#include <linux/math64.h>

#include "linux/mali_linux_trace.h"

#include "gator_events_mali_common.h"
#include "gator_events_mali_4xx.h"

/*
* There have been four different variants of the comms between gator and Mali depending on driver version:
* # | DDK vsn range             | Support                                                             | Notes
*
* 1 | (obsolete)                | No software counter support                                         | Obsolete patches
* 2 | (obsolete)                | Tracepoint called for each separate s/w counter value as it appears | Obsolete patches
* 3 | r3p0-04rel0 - r3p2-01rel2 | Single tracepoint for all s/w counters in a bundle.                 |
* 4 | r3p2-01rel3 - date        | As above but with extensions for MP devices (Mali-450)              | At least r4p0-00rel1
*/

#if !defined(GATOR_MALI_INTERFACE_STYLE)
#define GATOR_MALI_INTERFACE_STYLE (4)
#endif

#if GATOR_MALI_INTERFACE_STYLE == 1
#error GATOR_MALI_INTERFACE_STYLE 1 is obsolete
#elif GATOR_MALI_INTERFACE_STYLE == 2
#error GATOR_MALI_INTERFACE_STYLE 2 is obsolete
#elif GATOR_MALI_INTERFACE_STYLE >= 3
/* Valid GATOR_MALI_INTERFACE_STYLE */
#else
#error Unknown GATOR_MALI_INTERFACE_STYLE option.
#endif

#if GATOR_MALI_INTERFACE_STYLE < 4
#include "mali/mali_mjollnir_profiling_gator_api.h"
#else
#include "mali/mali_utgard_profiling_gator_api.h"
#endif

/*
 * Check that the MALI_SUPPORT define is set to one of the allowable device codes.
 */
#if (MALI_SUPPORT != MALI_4xx)
#error MALI_SUPPORT set to an invalid device code: expecting MALI_4xx
#endif

static const char mali_name[] = "4xx";

/* gatorfs variables for counter enable state,
 * the event the counter should count and the
 * 'key' (a unique id set by gatord and returned
 * by gator.ko)
 */
static unsigned long counter_enabled[NUMBER_OF_EVENTS];
static unsigned long counter_event[NUMBER_OF_EVENTS];
static unsigned long counter_key[NUMBER_OF_EVENTS];

/* The data we have recorded */
static atomic_t counter_data[NUMBER_OF_EVENTS];

/* An array used to return the data we recorded
 * as key,value pairs hence the *2
 */
static int counter_dump[NUMBER_OF_EVENTS * 2];
static int counter_prev[NUMBER_OF_EVENTS];
static bool prev_set[NUMBER_OF_EVENTS];

/* Note whether tracepoints have been registered */
static int trace_registered;

/*
 * These numbers define the actual numbers of each block type that exist in the system. Initially
 * these are set to the maxima defined above; if the driver is capable of being queried (newer
 * drivers only) then the values may be revised.
 */
static unsigned int n_vp_cores = MAX_NUM_VP_CORES;
static unsigned int n_l2_cores = MAX_NUM_L2_CACHE_CORES;
static unsigned int n_fp_cores = MAX_NUM_FP_CORES;

extern struct mali_counter mali_activity[2];
static const char *const mali_activity_names[] = {
    "fragment",
    "vertex",
};

/**
 * Returns non-zero if the given counter ID is an activity counter.
 */
static inline int is_activity_counter(unsigned int event_id)
{
    return (event_id >= FIRST_ACTIVITY_EVENT &&
        event_id <= LAST_ACTIVITY_EVENT);
}

/**
 * Returns non-zero if the given counter ID is a hardware counter.
 */
static inline int is_hw_counter(unsigned int event_id)
{
    return (event_id >= FIRST_HW_COUNTER && event_id <= LAST_HW_COUNTER);
}

/* Probe for hardware counter events */
GATOR_DEFINE_PROBE(mali_hw_counter, TP_PROTO(unsigned int event_id, unsigned int value))
{
    if (is_hw_counter(event_id))
        atomic_add(value, &counter_data[event_id]);
}

GATOR_DEFINE_PROBE(mali_sw_counters, TP_PROTO(pid_t pid, pid_t tid, void *surface_id, unsigned int *counters))
{
    u32 i;

    /* Copy over the values for those counters which are enabled. */
    for (i = FIRST_SW_COUNTER; i <= LAST_SW_COUNTER; i++) {
        if (counter_enabled[i])
            atomic_add(counters[i - FIRST_SW_COUNTER], &counter_data[i]);
    }
}

/**
 * Create a single filesystem entry for a specified event.
 * @param sb the superblock
 * @param root Filesystem root
 * @param name The name of the entry to create
 * @param event The ID of the event
 * @param create_event_item boolean indicating whether to create an 'event' filesystem entry. True to create.
 *
 * @return 0 if ok, non-zero if the create failed.
 */
static int create_fs_entry(struct super_block *sb, struct dentry *root, const char *name, int event, int create_event_item)
{
    struct dentry *dir;

    dir = gatorfs_mkdir(sb, root, name);

    if (!dir)
        return -1;

    if (create_event_item)
        gatorfs_create_ulong(sb, dir, "event", &counter_event[event]);

    gatorfs_create_ulong(sb, dir, "enabled", &counter_enabled[event]);
    gatorfs_create_ro_ulong(sb, dir, "key", &counter_key[event]);

    return 0;
}

#if GATOR_MALI_INTERFACE_STYLE > 3
/*
 * Read the version info structure if available
 */
static void initialise_version_info(void)
{
    void (*mali_profiling_get_mali_version_symbol)(struct _mali_profiling_mali_version *values);

    mali_profiling_get_mali_version_symbol = symbol_get(_mali_profiling_get_mali_version);

    if (mali_profiling_get_mali_version_symbol) {
        struct _mali_profiling_mali_version version_info;

        pr_debug("gator: mali online _mali_profiling_get_mali_version symbol @ %p\n",
                mali_profiling_get_mali_version_symbol);

        /*
         * Revise the number of each different core type using information derived from the DDK.
         */
        mali_profiling_get_mali_version_symbol(&version_info);

        n_fp_cores = version_info.num_of_fp_cores;
        n_vp_cores = version_info.num_of_vp_cores;
        n_l2_cores = version_info.num_of_l2_cores;

        /* Release the function - we're done with it. */
        symbol_put(_mali_profiling_get_mali_version);
    } else {
        pr_err("gator: mali online _mali_profiling_get_mali_version symbol not found\n");
        pr_err("gator:  check your Mali DDK version versus the GATOR_MALI_INTERFACE_STYLE setting\n");
    }
}
#endif

static int create_files(struct super_block *sb, struct dentry *root)
{
    int event;

    char buf[40];
    int core_id;
    int counter_number;

    pr_debug("gator: Initialising counters with style = %d\n", GATOR_MALI_INTERFACE_STYLE);

#if GATOR_MALI_INTERFACE_STYLE > 3
    /*
     * Initialise first: this sets up the number of cores available (on compatible DDK versions).
     * Ideally this would not need guarding but other parts of the code depend on the interface style being set
     * correctly; if it is not then the system can enter an inconsistent state.
     */
    initialise_version_info();
#endif

    mali_activity[0].cores = n_fp_cores;
    mali_activity[1].cores = n_vp_cores;
    for (event = 0; event < ARRAY_SIZE(mali_activity); event++) {
        if (gator_mali_create_file_system(mali_name, mali_activity_names[event], sb, root, &mali_activity[event], NULL) != 0)
            return -1;
    }

    /* Vertex processor counters */
    for (core_id = 0; core_id < n_vp_cores; core_id++) {
        int activity_counter_id = ACTIVITY_VP_0;

        snprintf(buf, sizeof(buf), "ARM_Mali-%s_VP_%d_active", mali_name, core_id);
        if (create_fs_entry(sb, root, buf, activity_counter_id, 0) != 0)
            return -1;

        for (counter_number = 0; counter_number < 2; counter_number++) {
            int counter_id = COUNTER_VP_0_C0 + (2 * core_id) + counter_number;

            snprintf(buf, sizeof(buf), "ARM_Mali-%s_VP_%d_cnt%d", mali_name, core_id, counter_number);
            if (create_fs_entry(sb, root, buf, counter_id, 1) != 0)
                return -1;
        }
    }

    /* Fragment processors' counters */
    for (core_id = 0; core_id < n_fp_cores; core_id++) {
        int activity_counter_id = ACTIVITY_FP_0 + core_id;

        snprintf(buf, sizeof(buf), "ARM_Mali-%s_FP_%d_active", mali_name, core_id);
        if (create_fs_entry(sb, root, buf, activity_counter_id, 0) != 0)
            return -1;

        for (counter_number = 0; counter_number < 2; counter_number++) {
            int counter_id = COUNTER_FP_0_C0 + (2 * core_id) + counter_number;

            snprintf(buf, sizeof(buf), "ARM_Mali-%s_FP_%d_cnt%d", mali_name, core_id, counter_number);
            if (create_fs_entry(sb, root, buf, counter_id, 1) != 0)
                return -1;
        }
    }

    /* L2 Cache counters */
    for (core_id = 0; core_id < n_l2_cores; core_id++) {
        for (counter_number = 0; counter_number < 2; counter_number++) {
            int counter_id = COUNTER_L2_0_C0 + (2 * core_id) + counter_number;

            snprintf(buf, sizeof(buf), "ARM_Mali-%s_L2_%d_cnt%d", mali_name, core_id, counter_number);
            if (create_fs_entry(sb, root, buf, counter_id, 1) != 0)
                return -1;
        }
    }

    /* Now set up the software counter entries */
    for (event = FIRST_SW_COUNTER; event <= LAST_SW_COUNTER; event++) {
        snprintf(buf, sizeof(buf), "ARM_Mali-%s_SW_%d", mali_name, event - FIRST_SW_COUNTER);

        if (create_fs_entry(sb, root, buf, event, 0) != 0)
            return -1;
    }

    /* Now set up the special counter entries */
    snprintf(buf, sizeof(buf), "ARM_Mali-%s_Filmstrip_cnt0", mali_name);
    if (create_fs_entry(sb, root, buf, COUNTER_FILMSTRIP, 1) != 0)
        return -1;

#ifdef DVFS_REPORTED_BY_DDK
    snprintf(buf, sizeof(buf), "ARM_Mali-%s_Frequency", mali_name);
    if (create_fs_entry(sb, root, buf, COUNTER_FREQUENCY, 1) != 0)
        return -1;

    snprintf(buf, sizeof(buf), "ARM_Mali-%s_Voltage", mali_name);
    if (create_fs_entry(sb, root, buf, COUNTER_VOLTAGE, 1) != 0)
        return -1;
#endif

    return 0;
}

/*
 * Local store for the get_counters entry point into the DDK.
 * This is stored here since it is used very regularly.
 */
static void (*mali_get_counters)(unsigned int *, unsigned int *, unsigned int *, unsigned int *);
static u32 (*mali_get_l2_counters)(struct _mali_profiling_l2_counter_values *values);

/*
 * Examine list of counters between two index limits and determine if any one is enabled.
 * Returns 1 if any counter is enabled, 0 if none is.
 */
static int is_any_counter_enabled(unsigned int first_counter, unsigned int last_counter)
{
    unsigned int i;

    for (i = first_counter; i <= last_counter; i++) {
        if (counter_enabled[i])
            return 1;   /* At least one counter is enabled */
    }

    return 0;       /* No s/w counters enabled */
}

static void init_counters(unsigned int from_counter, unsigned int to_counter)
{
    unsigned int counter_id;

    /* If a Mali driver is present and exporting the appropriate symbol
     * then we can request the HW counters (of which there are only 2)
     * be configured to count the desired events
     */
    mali_profiling_set_event_type *mali_set_hw_event;

    mali_set_hw_event = symbol_get(_mali_profiling_set_event);

    if (mali_set_hw_event) {
        pr_debug("gator: mali online _mali_profiling_set_event symbol @ %p\n", mali_set_hw_event);

        for (counter_id = from_counter; counter_id <= to_counter; counter_id++) {
            if (counter_enabled[counter_id])
                mali_set_hw_event(counter_id, counter_event[counter_id]);
            else
                mali_set_hw_event(counter_id, 0xFFFFFFFF);
        }

        symbol_put(_mali_profiling_set_event);
    } else {
        pr_err("gator: mali online _mali_profiling_set_event symbol not found\n");
    }
}

static void mali_counter_initialize(void)
{
    int i;

    mali_profiling_control_type *mali_control;

    init_counters(COUNTER_L2_0_C0, COUNTER_L2_0_C0 + (2 * n_l2_cores) - 1);
    init_counters(COUNTER_VP_0_C0, COUNTER_VP_0_C0 + (2 * n_vp_cores) - 1);
    init_counters(COUNTER_FP_0_C0, COUNTER_FP_0_C0 + (2 * n_fp_cores) - 1);

    /* Generic control interface for Mali DDK. */
    mali_control = symbol_get(_mali_profiling_control);
    if (mali_control) {
        /* The event attribute in the XML file keeps the actual frame rate. */
        unsigned int rate = counter_event[COUNTER_FILMSTRIP] & 0xff;
        unsigned int resize_factor = (counter_event[COUNTER_FILMSTRIP] >> 8) & 0xff;

        pr_debug("gator: mali online _mali_profiling_control symbol @ %p\n", mali_control);

        mali_control(SW_COUNTER_ENABLE, (is_any_counter_enabled(FIRST_SW_COUNTER, LAST_SW_COUNTER) ? 1 : 0));
        mali_control(FBDUMP_CONTROL_ENABLE, (counter_enabled[COUNTER_FILMSTRIP] ? 1 : 0));
        mali_control(FBDUMP_CONTROL_RATE, rate);
        mali_control(FBDUMP_CONTROL_RESIZE_FACTOR, resize_factor);

        pr_debug("gator: sent mali_control enabled=%d, rate=%d\n", (counter_enabled[COUNTER_FILMSTRIP] ? 1 : 0), rate);

        symbol_put(_mali_profiling_control);
    } else {
        pr_err("gator: mali online _mali_profiling_control symbol not found\n");
    }

    mali_get_counters = symbol_get(_mali_profiling_get_counters);
    if (mali_get_counters)
        pr_debug("gator: mali online _mali_profiling_get_counters symbol @ %p\n", mali_get_counters);
    else
        pr_debug("gator: mali _mali_profiling_get_counters symbol not defined\n");

    mali_get_l2_counters = symbol_get(_mali_profiling_get_l2_counters);
    if (mali_get_l2_counters)
        pr_debug("gator: mali online _mali_profiling_get_l2_counters symbol @ %p\n", mali_get_l2_counters);
    else
        pr_debug("gator: mali _mali_profiling_get_l2_counters symbol not defined\n");

    if (!mali_get_counters && !mali_get_l2_counters) {
        pr_err("gator: no L2 counters available\n");
        n_l2_cores = 0;
    }

    /* Clear counters in the start */
    for (i = 0; i < NUMBER_OF_EVENTS; i++) {
        atomic_set(&counter_data[i], 0);
        prev_set[i] = false;
    }
}

static void mali_counter_deinitialize(void)
{
    mali_profiling_set_event_type *mali_set_hw_event;
    mali_profiling_control_type *mali_control;

    mali_set_hw_event = symbol_get(_mali_profiling_set_event);

    if (mali_set_hw_event) {
        int i;

        pr_debug("gator: mali offline _mali_profiling_set_event symbol @ %p\n", mali_set_hw_event);
        for (i = FIRST_HW_COUNTER; i <= LAST_HW_COUNTER; i++)
            mali_set_hw_event(i, 0xFFFFFFFF);

        symbol_put(_mali_profiling_set_event);
    } else {
        pr_err("gator: mali offline _mali_profiling_set_event symbol not found\n");
    }

    /* Generic control interface for Mali DDK. */
    mali_control = symbol_get(_mali_profiling_control);

    if (mali_control) {
        pr_debug("gator: mali offline _mali_profiling_control symbol @ %p\n", mali_control);

        /* Reset the DDK state - disable counter collection */
        mali_control(SW_COUNTER_ENABLE, 0);

        mali_control(FBDUMP_CONTROL_ENABLE, 0);

        symbol_put(_mali_profiling_control);
    } else {
        pr_err("gator: mali offline _mali_profiling_control symbol not found\n");
    }

    if (mali_get_counters)
        symbol_put(_mali_profiling_get_counters);

    if (mali_get_l2_counters)
        symbol_put(_mali_profiling_get_l2_counters);
}

static int start(void)
{
    /* register tracepoints */
    if (GATOR_REGISTER_TRACE(mali_hw_counter)) {
        pr_err("gator: mali_hw_counter tracepoint failed to activate\n");
        return -1;
    }

    /* For Mali drivers with built-in support. */
    if (GATOR_REGISTER_TRACE(mali_sw_counters)) {
        pr_err("gator: mali_sw_counters tracepoint failed to activate\n");
        return -1;
    }

    trace_registered = 1;

    mali_counter_initialize();
    return 0;
}

static void stop(void)
{
    unsigned int cnt;

    pr_debug("gator: mali stop\n");

    if (trace_registered) {
        GATOR_UNREGISTER_TRACE(mali_hw_counter);

        /* For Mali drivers with built-in support. */
        GATOR_UNREGISTER_TRACE(mali_sw_counters);

        pr_debug("gator: mali timeline tracepoint deactivated\n");

        trace_registered = 0;
    }

    for (cnt = 0; cnt < NUMBER_OF_EVENTS; cnt++) {
        counter_enabled[cnt] = 0;
        counter_event[cnt] = 0;
    }

    mali_counter_deinitialize();
}

static void dump_counters(unsigned int from_counter, unsigned int to_counter, unsigned int *len)
{
    unsigned int counter_id;

    for (counter_id = from_counter; counter_id <= to_counter; counter_id++) {
        if (counter_enabled[counter_id]) {
            unsigned int value;

            counter_dump[(*len)++] = counter_key[counter_id];
            value = atomic_read(&counter_data[counter_id]);
            atomic_sub(value, &counter_data[counter_id]);
            counter_dump[(*len)++] = value;
        }
    }
}

static int read(int **buffer, bool sched_switch)
{
    int len = 0;

    if (!on_primary_core())
        return 0;

    /* Read the L2 C0 and C1 here. */
    if (n_l2_cores > 0 && is_any_counter_enabled(COUNTER_L2_0_C0, COUNTER_L2_0_C0 + (2 * n_l2_cores))) {
        unsigned int unavailable_l2_caches = 0;
        struct _mali_profiling_l2_counter_values cache_values;
        unsigned int cache_id;
        struct _mali_profiling_core_counters *per_core;

        /* Poke the driver to get the counter values - older style; only one L2 cache */
        if (mali_get_l2_counters) {
            unavailable_l2_caches = mali_get_l2_counters(&cache_values);
        } else if (mali_get_counters) {
            per_core = &cache_values.cores[0];
            mali_get_counters(&per_core->source0, &per_core->value0, &per_core->source1, &per_core->value1);
        } else {
            /* This should never happen, as n_l2_caches is only set > 0 if one of the above functions is found. */
        }

        /* Fill in the two cache counter values for each cache block. */
        for (cache_id = 0; cache_id < n_l2_cores; cache_id++) {
            unsigned int counter_id_0 = COUNTER_L2_0_C0 + (2 * cache_id);
            unsigned int counter_id_1 = counter_id_0 + 1;

            if ((1 << cache_id) & unavailable_l2_caches)
                continue; /* This cache is unavailable (powered-off, possibly). */

            per_core = &cache_values.cores[cache_id];

            if (counter_enabled[counter_id_0] && prev_set[counter_id_0]) {
                /* Calculate and save src0's counter val0 */
                counter_dump[len++] = counter_key[counter_id_0];
                counter_dump[len++] = per_core->value0 - counter_prev[counter_id_0];
            }

            if (counter_enabled[counter_id_1] && prev_set[counter_id_1]) {
                /* Calculate and save src1's counter val1 */
                counter_dump[len++] = counter_key[counter_id_1];
                counter_dump[len++] = per_core->value1 - counter_prev[counter_id_1];
            }

            /* Save the previous values for the counters. */
            counter_prev[counter_id_0] = per_core->value0;
            prev_set[counter_id_0] = true;
            counter_prev[counter_id_1] = per_core->value1;
            prev_set[counter_id_1] = true;
        }
    }

    /* Process other (non-timeline) counters. */
    dump_counters(COUNTER_VP_0_C0, COUNTER_VP_0_C0 + (2 * n_vp_cores) - 1, &len);
    dump_counters(COUNTER_FP_0_C0, COUNTER_FP_0_C0 + (2 * n_fp_cores) - 1, &len);

    dump_counters(FIRST_SW_COUNTER, LAST_SW_COUNTER, &len);

#ifdef DVFS_REPORTED_BY_DDK
    {
        int cnt;
        /*
         * Add in the voltage and frequency counters if enabled. Note
         * that, since these are actually passed as events, the counter
         * value should not be cleared.
         *
         * Intentionally use atomic_read as these are absolute counters
         */
        cnt = COUNTER_FREQUENCY;
        if (counter_enabled[cnt]) {
            counter_dump[len++] = counter_key[cnt];
            counter_dump[len++] = atomic_read(&counter_data[cnt]);
        }

        cnt = COUNTER_VOLTAGE;
        if (counter_enabled[cnt]) {
            counter_dump[len++] = counter_key[cnt];
            counter_dump[len++] = atomic_read(&counter_data[cnt]);
        }
    }
#endif

    if (buffer)
        *buffer = counter_dump;

    return len;
}

static struct gator_interface gator_events_mali_interface = {
    .name = "mali_4xx",
    .create_files = create_files,
    .start = start,
    .stop = stop,
    .read = read,
};

extern void gator_events_mali_log_dvfs_event(unsigned int frequency_mhz, unsigned int voltage_mv)
{
#ifdef DVFS_REPORTED_BY_DDK
    /* Intentionally use atomic_set as these are absolute counters */
    atomic_set(&counter_data[COUNTER_FREQUENCY], frequency_mhz);
    atomic_set(&counter_data[COUNTER_VOLTAGE], voltage_mv);
#endif
}

int gator_events_mali_init(void)
{
    unsigned int cnt;

    pr_debug("gator: mali init\n");

    gator_mali_initialise_counters(mali_activity, ARRAY_SIZE(mali_activity));

    for (cnt = 0; cnt < NUMBER_OF_EVENTS; cnt++) {
        counter_enabled[cnt] = 0;
        counter_event[cnt] = 0;
        counter_key[cnt] = gator_events_get_key();
        atomic_set(&counter_data[cnt], 0);
    }

    trace_registered = 0;

    return gator_events_install(&gator_events_mali_interface);
}
