// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/protocol/platform-defs.h>
#include <ddk/protocol/platform-device.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <threads.h>
#include <unistd.h>
#include <zircon/device/thermal.h>
#include "aml-scpi.h"
#include "aml-mailbox.h"

static scpi_opp_t* scpi_opp[MAX_DVFS_DOMAINS];

static zx_status_t aml_scpi_get_mailbox(uint32_t cmd,
                                        uint32_t* mailbox) {
    if (!mailbox || !VALID_CMD(cmd)) {
        return ZX_ERR_INVALID_ARGS;
    }

    for (uint32_t i = 0; i < countof(aml_low_priority_cmds); i++) {
        if (cmd == aml_low_priority_cmds[i]) {
            *mailbox = AP_NS_LOW_PRIORITY_MAILBOX;
            return ZX_OK;
        }
    }

    for (uint32_t i = 0; i < countof(aml_high_priority_cmds); i++) {
        if (cmd == aml_high_priority_cmds[i]) {
            *mailbox = AP_NS_HIGH_PRIORITY_MAILBOX;
            return ZX_OK;
        }
    }

    for (uint32_t i = 0; i < countof(aml_secure_cmds); i++) {
        if (cmd == aml_secure_cmds[i]) {
            *mailbox = AP_SECURE_MAILBOX;
            return ZX_OK;
        }
    }
    *mailbox = INVALID_MAILBOX;
    return ZX_ERR_NOT_FOUND;
}

static zx_status_t aml_scpi_execute_cmd(aml_scpi_t* scpi,
                                        void* rx_buf, size_t rx_size,
                                        void* tx_buf, size_t tx_size,
                                        uint32_t cmd, uint32_t client_id) {
    uint32_t mailbox_status = 0;
    mailbox_data_buf_t mdata;
    mdata.cmd = PACK_SCPI_CMD(cmd, client_id, 0);
    mdata.tx_buf = tx_buf;
    mdata.tx_size = tx_size;

    mailbox_channel_t channel;
    zx_status_t status = aml_scpi_get_mailbox(cmd, &channel.mailbox);
    if (status != ZX_OK) {
        SCPI_ERROR("aml_scpi_get_mailbox failed - error status %d\n", status);
        return status;
    }

    channel.rx_buf = rx_buf;
    channel.rx_size = rx_size;

    status = mailbox_send_cmd(&scpi->mailbox, &channel, &mdata);
    if (rx_buf) {
        mailbox_status = *(uint32_t*)(rx_buf);
    }
    if (status != ZX_OK || mailbox_status != 0) {
        SCPI_ERROR("mailbox_send_cmd failed - error status %d\n", status);
        return status;
    }
    return ZX_OK;
}

static zx_status_t aml_scpi_get_dvfs_info(void* ctx, uint8_t power_domain, scpi_opp_t* opps) {
    aml_scpi_t* scpi = ctx;
    zx_status_t status;
    struct {
        uint32_t status;
        uint8_t reserved;
        uint8_t operating_points;
        uint16_t latency;
        scpi_opp_entry_t opp[MAX_DVFS_OPPS];
    } __PACKED aml_dvfs_info;

    if (!opps || power_domain >= MAX_DVFS_DOMAINS) {
        return ZX_ERR_INVALID_ARGS;
    }

    mtx_lock(&scpi->lock);

    // dvfs info already populated
    if (scpi_opp[power_domain]) {
        memcpy(opps, scpi_opp[power_domain], sizeof(scpi_opp_t));
        mtx_unlock(&scpi->lock);
        return ZX_OK;
    }

    status = aml_scpi_execute_cmd(scpi,
                                  &aml_dvfs_info, sizeof(aml_dvfs_info),
                                  &power_domain, sizeof(power_domain),
                                  SCPI_CMD_GET_DVFS_INFO, SCPI_CL_DVFS);
    if (status != ZX_OK) {
        goto fail;
    }

    opps->count = aml_dvfs_info.operating_points;
    opps->latency = aml_dvfs_info.latency;

    if (opps->count > MAX_DVFS_OPPS) {
        SCPI_ERROR("Number of operating_points greater than MAX_DVFS_OPPS\n");
        status = ZX_ERR_INVALID_ARGS;
        goto fail;
    }

    zxlogf(INFO, "Cluster %u details\n", power_domain);
    zxlogf(INFO, "Number of operating_points %u\n", aml_dvfs_info.operating_points);
    zxlogf(INFO, "latency %u uS\n", aml_dvfs_info.latency);

    for (uint32_t i = 0; i < opps->count; i++) {
        opps->opp[i].freq_hz = aml_dvfs_info.opp[i].freq_hz;
        opps->opp[i].volt_mv = aml_dvfs_info.opp[i].volt_mv;
        zxlogf(INFO, "Operating point %d - ", i);
        zxlogf(INFO, "Freq %.4f Ghz ", (opps->opp[i].freq_hz) / (double)1000000000);
        zxlogf(INFO, "Voltage %.4f V\n", (opps->opp[i].volt_mv) / (double)1000);
    }

    scpi_opp[power_domain] = calloc(1, sizeof(scpi_opp_t));
    if (!scpi_opp[power_domain]) {
        status = ZX_ERR_NO_MEMORY;
        goto fail;
    }

    memcpy(scpi_opp[power_domain], opps, sizeof(scpi_opp_t));
    status = ZX_OK;

fail:
    mtx_unlock(&scpi->lock);
    return status;
}

static zx_status_t aml_scpi_get_dvfs_idx(void* ctx, uint8_t power_domain, uint16_t* idx) {
    aml_scpi_t* scpi = ctx;
    struct {
        uint32_t status;
        uint8_t idx;
    } __PACKED aml_dvfs_idx_info;

    if (!idx || power_domain >= MAX_DVFS_DOMAINS) {
        return ZX_ERR_INVALID_ARGS;
    }

    zx_status_t status = aml_scpi_execute_cmd(scpi,
                                              &aml_dvfs_idx_info, sizeof(aml_dvfs_idx_info),
                                              &power_domain, sizeof(power_domain),
                                              SCPI_CMD_GET_DVFS, SCPI_CL_DVFS);
    if (status != ZX_OK) {
        return status;
    }

    *idx = aml_dvfs_idx_info.idx;

    SCPI_ERROR("Current Operation point %x\n", aml_dvfs_idx_info.idx);
    return ZX_OK;
}

static zx_status_t aml_scpi_set_dvfs_idx(void* ctx, uint8_t power_domain, uint16_t idx) {
    aml_scpi_t* scpi = ctx;
    struct {
        uint8_t power_domain;
        uint16_t idx;
    } __PACKED aml_dvfs_idx_info;

    if (power_domain >= MAX_DVFS_DOMAINS) {
        return ZX_ERR_INVALID_ARGS;
    }

    aml_dvfs_idx_info.power_domain = power_domain;
    aml_dvfs_idx_info.idx = idx;

    SCPI_INFO("OPP index for cluster %d to %d\n", power_domain, idx);
    return aml_scpi_execute_cmd(scpi,
                                NULL, 0,
                                &aml_dvfs_idx_info, sizeof(aml_dvfs_idx_info),
                                SCPI_CMD_SET_DVFS, SCPI_CL_DVFS);
}

static zx_status_t aml_scpi_get_sensor_value(void* ctx, uint32_t sensor_id,
                                             uint32_t* sensor_value) {
    aml_scpi_t* scpi = ctx;
    struct {
        uint32_t status;
        uint16_t sensor_value;
    } __PACKED aml_sensor_val;

    if (!sensor_value) {
        return ZX_ERR_INVALID_ARGS;
    }

    zx_status_t status = aml_scpi_execute_cmd(scpi,
                                              &aml_sensor_val, sizeof(aml_sensor_val),
                                              &sensor_id, sizeof(sensor_id),
                                              SCPI_CMD_SENSOR_VALUE, SCPI_CL_THERMAL);
    if (status != ZX_OK) {
        return status;
    }
    *sensor_value = aml_sensor_val.sensor_value;
    return ZX_OK;
}

static zx_status_t aml_scpi_get_sensor(void* ctx, const char* name,
                                       uint32_t* sensor_value) {
    aml_scpi_t* scpi = ctx;
    struct {
        uint32_t status;
        uint16_t num_sensors;
    } __PACKED aml_sensor_cap;
    struct {
        uint32_t status;
        uint16_t sensor;
        uint8_t class;
        uint8_t trigger;
        char sensor_name[20];
    } __PACKED aml_sensor_info;

    if (sensor_value == NULL) {
        return ZX_ERR_INVALID_ARGS;
    }

    // First let's find information about all sensors
    zx_status_t status = aml_scpi_execute_cmd(scpi,
                                              &aml_sensor_cap, sizeof(aml_sensor_cap),
                                              NULL, 0,
                                              SCPI_CMD_SENSOR_CAPABILITIES, SCPI_CL_THERMAL);
    if (status != ZX_OK) {
        return status;
    }

    // Loop through all the sensors
    for (uint32_t sensor_id = 0; sensor_id < aml_sensor_cap.num_sensors; sensor_id++) {

        status = aml_scpi_execute_cmd(scpi,
                                      &aml_sensor_info, sizeof(aml_sensor_info),
                                      &sensor_id, sizeof(sensor_id),
                                      SCPI_CMD_SENSOR_INFO, SCPI_CL_THERMAL);
        if (status != ZX_OK) {
            return status;
        }
        if (!strncmp(name, aml_sensor_info.sensor_name, sizeof(aml_sensor_info.sensor_name))) {
            *sensor_value = sensor_id;
            break;
        }
    }
    return ZX_OK;
}

static void aml_scpi_release(void* ctx) {
    aml_scpi_t* scpi = ctx;
    free(scpi);
}

static zx_protocol_device_t aml_scpi_device_protocol = {
    .version = DEVICE_OPS_VERSION,
    .release = aml_scpi_release,
};

static scpi_protocol_ops_t scpi_ops = {
    .get_sensor = aml_scpi_get_sensor,
    .get_sensor_value = aml_scpi_get_sensor_value,
    .get_dvfs_info = aml_scpi_get_dvfs_info,
    .get_dvfs_idx = aml_scpi_get_dvfs_idx,
    .set_dvfs_idx = aml_scpi_set_dvfs_idx,
};

static zx_status_t aml_scpi_bind(void* ctx, zx_device_t* parent) {
    zx_status_t status = ZX_OK;

    aml_scpi_t* scpi = calloc(1, sizeof(aml_scpi_t));
    if (!scpi) {
        return ZX_ERR_NO_MEMORY;
    }
    mtx_init(&scpi->lock, mtx_plain);

printf("aml_scpi_bind 1\n");
    status = device_get_protocol(parent, ZX_PROTOCOL_PLATFORM_DEV, &scpi->pdev);
    if (status != ZX_OK) {
        SCPI_ERROR("Could not get parent protocol\n");
        goto fail;
    }
printf("aml_scpi_bind 2\n");
    status = device_get_protocol(parent, ZX_PROTOCOL_MAILBOX, &scpi->mailbox);
    if (status != ZX_OK) {
        SCPI_ERROR("Could not get Mailbox protocol\n");
        goto fail;
    }

printf("aml_scpi_bind 3\n");
    zx_device_prop_t props[] = {
        {BIND_PLATFORM_DEV_VID, 0, PDEV_VID_AMLOGIC},
        {BIND_PLATFORM_DEV_PID, 0, PDEV_PID_GENERIC},
        {BIND_PLATFORM_DEV_DID, 0, PDEV_DID_AMLOGIC_THERMAL},
    };

    device_add_args_t args = {
        .version = DEVICE_ADD_ARGS_VERSION,
        .name = "aml-scpi",
        .ctx = scpi,
        .ops = &aml_scpi_device_protocol,
        .proto_id = ZX_PROTOCOL_SCPI,
        .proto_ops = &scpi_ops,
        .props = props,
        .prop_count = countof(props),
    };

    status = pdev_device_add(&scpi->pdev, 0, &args, NULL);
    if (status != ZX_OK) {
        goto fail;
    }

printf("aml_scpi_bind 4\n");

    return ZX_OK;
fail:
    aml_scpi_release(scpi);
    return ZX_OK;
}

static zx_driver_ops_t aml_scpi_driver_ops = {
    .version = DRIVER_OPS_VERSION,
    .bind = aml_scpi_bind,
};

ZIRCON_DRIVER_BEGIN(aml_scpi, aml_scpi_driver_ops, "zircon", "0.1", 4)
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PLATFORM_DEV),
    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_KHADAS),
    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_PID, PDEV_PID_VIM2),
    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_DID, PDEV_DID_AMLOGIC_SCPI),
ZIRCON_DRIVER_END(aml_scpi)
