/*
 * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include <assert.h>
#include <stdint.h>
#include <stdbool.h>

#include <camkes/io.h>
#include <platsupport/clock.h>
#include <utils/util.h>

#include "plat.h"

typedef struct clock_entry {
    bool initialised;
    seL4_Word owner;
    clk_t *clk;
} clock_entry_t;

static ps_io_ops_t *ops;
static clock_entry_t *clock_table;

/* Prototypes for these functions are not generated by the camkes templates yet */
seL4_Word the_clock_get_sender_id(void);

static inline bool check_clk_initialised(clk_id_t clk_id)
{
    return clock_table[clk_id].initialised;
}

static inline bool check_valid_clk_id(clk_id_t clk_id)
{
    return (clk_id >= 0 && clk_id < NCLOCKS);
}

static inline bool check_valid_clock_gate(clock_gate_t clock_gate)
{
    return (clock_gate >= 0 && clock_gate <= NCLKGATES);
}

static inline bool check_is_owner(clk_id_t clk_id, seL4_Word client_id)
{
    return (clock_table[clk_id].owner == client_id);
}

static inline seL4_Word get_client_id(void)
{
    return the_clock_get_sender_id();
}

int the_clock_init_clock(clk_id_t clk_id)
{
    int error = 0;

    if (!check_valid_clk_id(clk_id)) {
        ZF_LOGE("Invalid clock ID");
        error = -EINVAL;
        goto out;
    }

    seL4_Word client_id = get_client_id();

    if (check_clk_initialised(clk_id)) {
        if (!check_is_owner(clk_id, client_id)) {
            ZF_LOGE("Clock is already initialised by another owner");
            error = -EBUSY;
            goto out;
        } else {
            error = 0;
            goto out;
        }
    }

    clock_table[clk_id].clk = clk_get_clock(&ops->clock_sys, clk_id);
    if (!clock_table[clk_id].clk) {
        ZF_LOGE("Failed to get clock for clock ID %d", clk_id);
        error = -ENODEV;
        goto out;
    }

    clock_table[clk_id].initialised = true;
    clock_table[clk_id].owner = client_id;

out:
    return error;
}

int the_clock_set_gate_mode(clock_gate_t gate, clock_gate_mode_t mode)
{
    /* TODO Some basic form of access control to the gates?,
     * Don't want a component to turn off the clock underneath another component */
    int error = clk_gate_enable(&ops->clock_sys, gate, mode);

    return error;
}

freq_t the_clock_get_freq(clk_id_t clk_id)
{
    freq_t freq = 0;

    if (!check_valid_clk_id(clk_id)) {
        ZF_LOGE("Invalid clock ID");
        freq = 0;
        goto out;
    }

    seL4_Word client_id = get_client_id();

    if (!check_clk_initialised(clk_id)) {
        ZF_LOGE("Clock isn't initialised");
        freq = 0;
        goto out;
    }

    if (!check_is_owner(clk_id, client_id)) {
        ZF_LOGE("Client is not the owner of this clock");
        freq = 0;
        goto out;
    }

    freq = clk_get_freq(clock_table[clk_id].clk);

out:
    return freq;
}

freq_t the_clock_set_freq(clk_id_t clk_id, freq_t hz)
{
    freq_t set_freq = 0;

    if (!check_valid_clk_id(clk_id)) {
        ZF_LOGE("Invalid clock ID");
        set_freq = 0;
        goto out;
    }

    seL4_Word client_id = get_client_id();

    if (!check_clk_initialised(clk_id)) {
        ZF_LOGE("Clock isn't initialised");
        set_freq = 0;
        goto out;
    }

    if (!check_is_owner(clk_id, client_id)) {
        ZF_LOGE("Client is not the owner of this clock");
        set_freq = 0;
        goto out;
    }

    set_freq = clk_set_freq(clock_table[clk_id].clk, hz);

out:
    return set_freq;
}

int the_clock_register_child(clk_id_t parent, clk_id_t child)
{
    int error = 0;

    if (!check_valid_clk_id(parent) || !check_valid_clk_id(child)) {
        error = -EINVAL;
        goto out;
    }

    seL4_Word client_id = get_client_id();

    if (!check_clk_initialised(parent)) {
        ZF_LOGE("Parent clock isn't initialised");
        error = -EPERM;
        goto out;
    }

    if (!check_is_owner(parent, client_id)) {
        ZF_LOGE("Client is not the owner of the parent clock");
        error = -EPERM;
        goto out;
    }

    if (!check_clk_initialised(child)) {
        ZF_LOGE("Child clock isn't initialised");
        error = -EPERM;
        goto out;
    }

    if (!check_is_owner(child, client_id)) {
        ZF_LOGE("Client is not the owner of the child clock");
        error = -EPERM;
        goto out;
    }

    clk_register_child(clock_table[parent].clk, clock_table[child].clk);
    error = 0;

out:
    return error;
}

int ClockServer_init(ps_io_ops_t *io_ops)
{
    ops = io_ops;
    int error;
    if (plat_init) {
        /* Perform some platform specific initialisation before initialising
         * the clock subsystem */
        error = plat_init(ops);
        ZF_LOGF_IF(error, "Failed to perform the platform initialisation");
    }

    error = clock_sys_init(ops, &ops->clock_sys);
    ZF_LOGF_IF(error, "Failed to initialise the clock subsystem");

    error = ps_calloc(&ops->malloc_ops, 1, sizeof(*clock_table) * NCLOCKS, (void **) &clock_table);
    ZF_LOGF_IF(error, "Failed to allocate memory for the clock table");
    return 0;
}
