/*
 * SPDX-FileCopyrightText: Copyright 2022 Arm Limited and/or its affiliates <open-source-office@arm.com>
 * SPDX-License-Identifier: Apache-2.0
 *
 * 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.
 */

#include "ethosu_profiler.h"
#include "log_macros.h"

#include <string.h>

extern struct ethosu_driver ethosu_drv;     /* Default Arm Ethos-U NPU device driver object */
static ethosu_pmu_counters npu_counters;    /* NPU counter local instance */
static const char* unit_beats = "beats";
static const char* unit_cycles = "cycles";

/**
 * @brief Gets the npu counter instance to be used.
 * @return Pointer to the npu counter instance.
 */
static ethosu_pmu_counters* get_counter_instance(void)
{
    return &npu_counters;
}

/**
 * @brief Checks if the counter has overflown.
 * @param pmu_counter_mask  Mask for the event counter.
 * @return  true if overflow is detected, false otherwise.
 */
static bool counter_overflow(uint32_t pmu_counter_mask)
{
    /* Check for overflow: The idle counter is 32 bit while the
       total cycle count is 64 bit. */
    const uint32_t overflow_status = ETHOSU_PMU_Get_CNTR_OVS(&ethosu_drv);
    return pmu_counter_mask & overflow_status ? true : false;
}

void ethosu_pmu_init(void)
{
    uint32_t i = 0;
    uint32_t evt_mask = ETHOSU_PMU_CCNT_Msk;
    ethosu_pmu_counters* counters = get_counter_instance();
    memset(counters, 0, sizeof(*counters));

    /* Total counters = event counters + derived counters + total cycle count */
    counters->num_total_counters = ETHOSU_PROFILER_NUM_COUNTERS;

#if ETHOSU_PMU_NCOUNTERS >= 4
    counters->npu_evt_counters[0].event_type = ETHOSU_PMU_NPU_IDLE;
    counters->npu_evt_counters[0].event_mask = ETHOSU_PMU_CNT1_Msk;
    counters->npu_evt_counters[0].name = "NPU IDLE";
    counters->npu_evt_counters[0].unit = unit_cycles;

    counters->npu_evt_counters[1].event_type = ETHOSU_PMU_AXI0_RD_DATA_BEAT_RECEIVED;
    counters->npu_evt_counters[1].event_mask = ETHOSU_PMU_CNT2_Msk;
    counters->npu_evt_counters[1].name = "NPU AXI0_RD_DATA_BEAT_RECEIVED";
    counters->npu_evt_counters[1].unit = unit_beats;

    counters->npu_evt_counters[2].event_type = ETHOSU_PMU_AXI0_WR_DATA_BEAT_WRITTEN;
    counters->npu_evt_counters[2].event_mask = ETHOSU_PMU_CNT3_Msk;
    counters->npu_evt_counters[2].name = "NPU AXI0_WR_DATA_BEAT_WRITTEN";
    counters->npu_evt_counters[2].unit = unit_beats;

    counters->npu_evt_counters[3].event_type = ETHOSU_PMU_AXI1_RD_DATA_BEAT_RECEIVED;
    counters->npu_evt_counters[3].event_mask = ETHOSU_PMU_CNT4_Msk;
    counters->npu_evt_counters[3].name = "NPU AXI1_RD_DATA_BEAT_RECEIVED";
    counters->npu_evt_counters[3].unit = unit_beats;
#else /* ETHOSU_PMU_NCOUNTERS >= 4 */
    #error "NPU PMU expects a minimum of 4 available event triggered counters!"
#endif /* ETHOSU_PMU_NCOUNTERS >= 4 */

#if ETHOSU_DERIVED_NCOUNTERS >= 1
    counters->npu_derived_counters[0].name = "NPU ACTIVE";
    counters->npu_derived_counters[0].unit = unit_cycles;
#endif /* ETHOSU_DERIVED_NCOUNTERS >= 1 */

    for (i = 0; i < ETHOSU_PMU_NCOUNTERS; ++i) {
        ETHOSU_PMU_Set_EVTYPER(&ethosu_drv, i, counters->npu_evt_counters[i].event_type);
        evt_mask |= counters->npu_evt_counters[i].event_mask;
    }

    /* Reset overflow status. */
    ETHOSU_PMU_Set_CNTR_OVS(&ethosu_drv, evt_mask);

    /* Enable PMU. */
    ETHOSU_PMU_Enable(&ethosu_drv);

    /* Enable counters for cycle and event counters. */
    ETHOSU_PMU_CNTR_Disable(&ethosu_drv, evt_mask);
    ethosu_pmu_reset_counters();
    ETHOSU_PMU_CNTR_Enable(&ethosu_drv, evt_mask);
}

/**
 * @brief  Resets the Arm Ethos-U NPU PMU counters.
 */
void ethosu_pmu_reset_counters(void)
{
    /* Reset all cycle and event counters. */
    ETHOSU_PMU_CYCCNT_Reset(&ethosu_drv);
    ETHOSU_PMU_EVCNTR_ALL_Reset(&ethosu_drv);
}

/**
 * @brief Get the Arm Ethos-U NPU PMU counters
 * @return ethosu_pmu_counters
 */
ethosu_pmu_counters ethosu_get_pmu_counters(void)
{
    ethosu_pmu_counters* counters = get_counter_instance();
    uint32_t i = 0;

    /* Event counters */
    for (i = 0; i < ETHOSU_PMU_NCOUNTERS; ++i) {
        if (counter_overflow(counters->npu_evt_counters[i].event_mask)) {
            warn("Counter overflow detected for %s.\n", counters->npu_evt_counters[i].name);
        }
        counters->npu_evt_counters[i].counter_value =
            ETHOSU_PMU_Get_EVCNTR(&ethosu_drv, i);
    }

    /* Total cycle count */
    counters->npu_total_ccnt = ETHOSU_PMU_Get_CCNTR(&ethosu_drv);

    /* Derived counters */
#if ETHOSU_DERIVED_NCOUNTERS >= 1
    if (counters->npu_evt_counters[0].event_type == ETHOSU_PMU_NPU_IDLE) {
        counters->npu_derived_counters[0].counter_value =
            counters->npu_total_ccnt - counters->npu_evt_counters[0].counter_value;
    }
#endif /* ETHOSU_DERIVED_NCOUNTERS >= 1 */

    return *counters;
}
