/*
 * Copyright (c) 2022 Arm Limited. All rights reserved.
 * 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 "timer_mps3.h"

#include "log_macros.h"
#include "smm_mps3.h"   /* Memory map for MPS3. */

static uint64_t cpu_cycle_count = 0;    /* 64-bit cpu cycle counter */

/**
 * @brief   Gets the system tick triggered cycle counter for the CPU.
 * @return  64-bit counter value.
 **/
static uint64_t Get_SysTick_Cycle_Count(void);

/**
 * SysTick initialisation
 */
static int Init_SysTick(void);

void timer_reset(void)
{
    MPS3_FPGAIO->CLK1HZ   = 0;
    MPS3_FPGAIO->CLK100HZ = 0;
    MPS3_FPGAIO->COUNTER  = 0;

    if (0 != Init_SysTick()) {
        printf_err("Failed to initialise system tick config\n");
    }
    debug("system tick config ready\n");
}

base_time_counter get_time_counter(void)
{
    base_time_counter t = {
        .counter_1Hz        = MPS3_FPGAIO->CLK1HZ,
        .counter_100Hz      = MPS3_FPGAIO->CLK100HZ,
        .counter_fpga       = MPS3_FPGAIO->COUNTER,
        .counter_systick    = Get_SysTick_Cycle_Count()
    };
    debug("Timestamp:\n");
    debug("\tCounter 1 Hz:   %" PRIu32 "\n", t.counter_1Hz);
    debug("\tCounter 100 Hz: %" PRIu32 "\n", t.counter_100Hz);
    debug("\tCounter FPGA:   %" PRIu32 "\n", t.counter_fpga);
    debug("\tCounter CPU:    %" PRIu64 "\n", t.counter_systick);
    return t;
}

/**
 * Please note, that there are no checks for overflow in this function => if
 * the time elapsed has been big (in days) this could happen and is currently
 * not handled.
 **/
uint32_t get_duration_milliseconds(base_time_counter *start,
                                   base_time_counter *end)
{
    uint32_t time_elapsed = 0;
    if (end->counter_100Hz > start->counter_100Hz) {
        time_elapsed = (end->counter_100Hz - start->counter_100Hz) * 10;
    } else {
        time_elapsed = (end->counter_1Hz - start->counter_1Hz) * 1000 +
            ((0xFFFFFFFF - start->counter_100Hz) + end->counter_100Hz + 1) * 10;
    }

    /* If the time elapsed is less than 100ms, use microseconds count to be
     * more precise */
    if (time_elapsed < 100) {
        debug("Using the microsecond function instead..\n");
        return get_duration_microseconds(start, end)/1000;
    }

    return time_elapsed;
}

/**
 * Like the microsecond counterpart, this function could return wrong results when
 * the counter (MAINCLK) overflows. There are no overflow counters available.
 **/
uint32_t get_duration_microseconds(base_time_counter *start,
                                   base_time_counter *end)
{
    const int divisor = get_mps3_core_clock()/1000000;
    uint32_t time_elapsed = 0;
    if (end->counter_fpga > start->counter_fpga) {
        time_elapsed = (end->counter_fpga - start->counter_fpga)/divisor;
    } else {
        time_elapsed = ((0xFFFFFFFF - end->counter_fpga)
            + start->counter_fpga + 1)/divisor;
    }
    return time_elapsed;
}

uint64_t get_cycle_count_diff(base_time_counter *start,
                              base_time_counter *end)
{
    if (start->counter_systick > end->counter_systick) {
        warn("start > end; counter might have overflown\n");
    }
    return end->counter_systick - start->counter_systick;
}

void start_cycle_counter(void)
{
    /* Nothing to do for FPGA */
}

void stop_cycle_counter(void)
{
    /* Nothing to do for FPGA */
}

void SysTick_Handler(void)
{
    /* Increment the cycle counter based on load value. */
    cpu_cycle_count += SysTick->LOAD + 1;
}

/**
 * Gets the current SysTick derived counter value
 */
static uint64_t Get_SysTick_Cycle_Count(void)
{
    uint32_t systick_val;

    NVIC_DisableIRQ(SysTick_IRQn);
    systick_val = SysTick->VAL & SysTick_VAL_CURRENT_Msk;
    NVIC_EnableIRQ(SysTick_IRQn);

    return cpu_cycle_count + (SysTick->LOAD - systick_val);
}


/**
 * SysTick initialisation
 */
static int Init_SysTick(void)
{
    const uint32_t ticks_10ms = get_mps3_core_clock()/100 + 1;
    int err = 0;

    /* Reset CPU cycle count value. */
    cpu_cycle_count = 0;

    /* Changing configuration for sys tick => guard from being
     * interrupted. */
    NVIC_DisableIRQ(SysTick_IRQn);

    /* SysTick init - this will enable interrupt too. */
    err = SysTick_Config(ticks_10ms);

    /* Enable interrupt again. */
    NVIC_EnableIRQ(SysTick_IRQn);

    /* Wait for SysTick to kick off */
    while (!err && !SysTick->VAL) {
        __NOP();
    }

    return err;
}

uint32_t get_mps3_core_clock(void)
{
    const uint32_t default_clock = 32000000 /* 32 MHz clock */;
    static int warned_once = 0;
    if (0 != MPS3_SCC->CFG_ACLK) {
        if (default_clock != MPS3_SCC->CFG_ACLK) {
            warn("System clock is different to the MPS3 config set clock.\n");
        }
        return MPS3_SCC->CFG_ACLK;
    }

    if (!warned_once) {
        warn("MPS3_SCC->CFG_ACLK reads 0. Assuming default clock of %" PRIu32 "\n",
            default_clock);
        warned_once = 1;
    }
    return default_clock;
}