/*
 * QTests for Nuvoton NPCM7xx ADCModules.
 *
 * Copyright 2020 Google LLC
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
 * for more details.
 */

#include "qemu/osdep.h"
#include "qemu/bitops.h"
#include "qemu/timer.h"
#include "libqtest.h"
#include "qapi/qmp/qdict.h"

#define REF_HZ          (25000000)

#define CON_OFFSET      0x0
#define DATA_OFFSET     0x4

#define NUM_INPUTS      8
#define DEFAULT_IREF    2000000
#define CONV_CYCLES     20
#define RESET_CYCLES    10
#define R0_INPUT        500000
#define R1_INPUT        1500000
#define MAX_RESULT      1023

#define DEFAULT_CLKDIV  5

#define FUSE_ARRAY_BA   0xf018a000
#define FCTL_OFFSET     0x14
#define FST_OFFSET      0x0
#define FADDR_OFFSET    0x4
#define FDATA_OFFSET    0x8
#define ADC_CALIB_ADDR  24
#define FUSE_READ       0x2

/* Register field definitions. */
#define CON_MUX(rv) ((rv) << 24)
#define CON_INT_EN  BIT(21)
#define CON_REFSEL  BIT(19)
#define CON_INT     BIT(18)
#define CON_EN      BIT(17)
#define CON_RST     BIT(16)
#define CON_CONV    BIT(13)
#define CON_DIV(rv) extract32(rv, 1, 8)

#define FST_RDST    BIT(1)
#define FDATA_MASK  0xff

#define MAX_ERROR   10000
#define MIN_CALIB_INPUT 100000
#define MAX_CALIB_INPUT 1800000

static const uint32_t input_list[] = {
    100000,
    500000,
    1000000,
    1500000,
    1800000,
    2000000,
};

static const uint32_t vref_list[] = {
    2000000,
    2200000,
    2500000,
};

static const uint32_t iref_list[] = {
    1800000,
    1900000,
    2000000,
    2100000,
    2200000,
};

static const uint32_t div_list[] = {0, 1, 3, 7, 15};

typedef struct ADC {
    int irq;
    uint64_t base_addr;
} ADC;

ADC adc_defs = {
    .irq        = 0,
    .base_addr  = 0xf000c000
};

static uint32_t adc_read_con(QTestState *qts, const ADC *adc)
{
    return qtest_readl(qts, adc->base_addr + CON_OFFSET);
}

static void adc_write_con(QTestState *qts, const ADC *adc, uint32_t value)
{
    qtest_writel(qts, adc->base_addr + CON_OFFSET, value);
}

static uint32_t adc_read_data(QTestState *qts, const ADC *adc)
{
    return qtest_readl(qts, adc->base_addr + DATA_OFFSET);
}

static uint32_t adc_calibrate(uint32_t measured, uint32_t *rv)
{
    return R0_INPUT + (R1_INPUT - R0_INPUT) * (int32_t)(measured - rv[0])
        / (int32_t)(rv[1] - rv[0]);
}

static void adc_qom_set(QTestState *qts, const ADC *adc,
        const char *name, uint32_t value)
{
    QDict *response;
    const char *path = "/machine/soc/adc";

    g_test_message("Setting properties %s of %s with value %u",
            name, path, value);
    response = qtest_qmp(qts, "{ 'execute': 'qom-set',"
            " 'arguments': { 'path': %s, 'property': %s, 'value': %u}}",
            path, name, value);
    /* The qom set message returns successfully. */
    g_assert_true(qdict_haskey(response, "return"));
    qobject_unref(response);
}

static void adc_write_input(QTestState *qts, const ADC *adc,
        uint32_t index, uint32_t value)
{
    char name[100];

    sprintf(name, "adci[%u]", index);
    adc_qom_set(qts, adc, name, value);
}

static void adc_write_vref(QTestState *qts, const ADC *adc, uint32_t value)
{
    adc_qom_set(qts, adc, "vref", value);
}

static uint32_t adc_calculate_output(uint32_t input, uint32_t ref)
{
    uint32_t output;

    g_assert_cmpuint(input, <=, ref);
    output = (input * (MAX_RESULT + 1)) / ref;
    if (output > MAX_RESULT) {
        output = MAX_RESULT;
    }

    return output;
}

static uint32_t adc_prescaler(QTestState *qts, const ADC *adc)
{
    uint32_t div = extract32(adc_read_con(qts, adc), 1, 8);

    return 2 * (div + 1);
}

static int64_t adc_calculate_steps(uint32_t cycles, uint32_t prescale,
        uint32_t clkdiv)
{
    return (NANOSECONDS_PER_SECOND / (REF_HZ >> clkdiv)) * cycles * prescale;
}

static void adc_wait_conv_finished(QTestState *qts, const ADC *adc,
        uint32_t clkdiv)
{
    uint32_t prescaler = adc_prescaler(qts, adc);

    /*
     * ADC should takes roughly 20 cycles to convert one sample. So we assert it
     * should take 10~30 cycles here.
     */
    qtest_clock_step(qts, adc_calculate_steps(CONV_CYCLES / 2, prescaler,
                clkdiv));
    /* ADC is still converting. */
    g_assert_true(adc_read_con(qts, adc) & CON_CONV);
    qtest_clock_step(qts, adc_calculate_steps(CONV_CYCLES, prescaler, clkdiv));
    /* ADC has finished conversion. */
    g_assert_false(adc_read_con(qts, adc) & CON_CONV);
}

/* Check ADC can be reset to default value. */
static void test_init(gconstpointer adc_p)
{
    const ADC *adc = adc_p;

    QTestState *qts = qtest_init("-machine quanta-gsj");
    adc_write_con(qts, adc, CON_REFSEL | CON_INT);
    g_assert_cmphex(adc_read_con(qts, adc), ==, CON_REFSEL);
    qtest_quit(qts);
}

/* Check ADC can convert from an internal reference. */
static void test_convert_internal(gconstpointer adc_p)
{
    const ADC *adc = adc_p;
    uint32_t index, input, output, expected_output;
    QTestState *qts = qtest_init("-machine quanta-gsj");
    qtest_irq_intercept_in(qts, "/machine/soc/a9mpcore/gic");

    for (index = 0; index < NUM_INPUTS; ++index) {
        for (size_t i = 0; i < ARRAY_SIZE(input_list); ++i) {
            input = input_list[i];
            expected_output = adc_calculate_output(input, DEFAULT_IREF);

            adc_write_input(qts, adc, index, input);
            adc_write_con(qts, adc, CON_MUX(index) | CON_REFSEL | CON_INT |
                    CON_EN | CON_CONV);
            adc_wait_conv_finished(qts, adc, DEFAULT_CLKDIV);
            g_assert_cmphex(adc_read_con(qts, adc), ==, CON_MUX(index) |
                    CON_REFSEL | CON_EN);
            g_assert_false(qtest_get_irq(qts, adc->irq));
            output = adc_read_data(qts, adc);
            g_assert_cmpuint(output, ==, expected_output);
        }
    }

    qtest_quit(qts);
}

/* Check ADC can convert from an external reference. */
static void test_convert_external(gconstpointer adc_p)
{
    const ADC *adc = adc_p;
    uint32_t index, input, vref, output, expected_output;
    QTestState *qts = qtest_init("-machine quanta-gsj");
    qtest_irq_intercept_in(qts, "/machine/soc/a9mpcore/gic");

    for (index = 0; index < NUM_INPUTS; ++index) {
        for (size_t i = 0; i < ARRAY_SIZE(input_list); ++i) {
            for (size_t j = 0; j < ARRAY_SIZE(vref_list); ++j) {
                input = input_list[i];
                vref = vref_list[j];
                expected_output = adc_calculate_output(input, vref);

                adc_write_input(qts, adc, index, input);
                adc_write_vref(qts, adc, vref);
                adc_write_con(qts, adc, CON_MUX(index) | CON_INT | CON_EN |
                        CON_CONV);
                adc_wait_conv_finished(qts, adc, DEFAULT_CLKDIV);
                g_assert_cmphex(adc_read_con(qts, adc), ==,
                        CON_MUX(index) | CON_EN);
                g_assert_false(qtest_get_irq(qts, adc->irq));
                output = adc_read_data(qts, adc);
                g_assert_cmpuint(output, ==, expected_output);
            }
        }
    }

    qtest_quit(qts);
}

/* Check ADC interrupt files if and only if CON_INT_EN is set. */
static void test_interrupt(gconstpointer adc_p)
{
    const ADC *adc = adc_p;
    uint32_t index, input, output, expected_output;
    QTestState *qts = qtest_init("-machine quanta-gsj");

    index = 1;
    input = input_list[1];
    expected_output = adc_calculate_output(input, DEFAULT_IREF);

    qtest_irq_intercept_in(qts, "/machine/soc/a9mpcore/gic");
    adc_write_input(qts, adc, index, input);
    g_assert_false(qtest_get_irq(qts, adc->irq));
    adc_write_con(qts, adc, CON_MUX(index) | CON_INT_EN | CON_REFSEL | CON_INT
            | CON_EN | CON_CONV);
    adc_wait_conv_finished(qts, adc, DEFAULT_CLKDIV);
    g_assert_cmphex(adc_read_con(qts, adc), ==, CON_MUX(index) | CON_INT_EN
            | CON_REFSEL | CON_INT | CON_EN);
    g_assert_true(qtest_get_irq(qts, adc->irq));
    output = adc_read_data(qts, adc);
    g_assert_cmpuint(output, ==, expected_output);

    qtest_quit(qts);
}

/* Check ADC is reset after setting ADC_RST for 10 ADC cycles. */
static void test_reset(gconstpointer adc_p)
{
    const ADC *adc = adc_p;
    QTestState *qts = qtest_init("-machine quanta-gsj");

    for (size_t i = 0; i < ARRAY_SIZE(div_list); ++i) {
        uint32_t div = div_list[i];

        adc_write_con(qts, adc, CON_INT | CON_EN | CON_RST | CON_DIV(div));
        qtest_clock_step(qts, adc_calculate_steps(RESET_CYCLES,
                    adc_prescaler(qts, adc), DEFAULT_CLKDIV));
        g_assert_false(adc_read_con(qts, adc) & CON_EN);
    }
    qtest_quit(qts);
}

/* Check ADC Calibration works as desired. */
static void test_calibrate(gconstpointer adc_p)
{
    int i, j;
    const ADC *adc = adc_p;

    for (j = 0; j < ARRAY_SIZE(iref_list); ++j) {
        uint32_t iref = iref_list[j];
        uint32_t expected_rv[] = {
            adc_calculate_output(R0_INPUT, iref),
            adc_calculate_output(R1_INPUT, iref),
        };
        char buf[100];
        QTestState *qts;

        sprintf(buf, "-machine quanta-gsj -global npcm7xx-adc.iref=%u", iref);
        qts = qtest_init(buf);

        /* Check the converted value is correct using the calibration value. */
        for (i = 0; i < ARRAY_SIZE(input_list); ++i) {
            uint32_t input;
            uint32_t output;
            uint32_t expected_output;
            uint32_t calibrated_voltage;
            uint32_t index = 0;

            input = input_list[i];
            /* Calibration only works for input range 0.1V ~ 1.8V. */
            if (input < MIN_CALIB_INPUT || input > MAX_CALIB_INPUT) {
                continue;
            }
            expected_output = adc_calculate_output(input, iref);

            adc_write_input(qts, adc, index, input);
            adc_write_con(qts, adc, CON_MUX(index) | CON_REFSEL | CON_INT |
                    CON_EN | CON_CONV);
            adc_wait_conv_finished(qts, adc, DEFAULT_CLKDIV);
            g_assert_cmphex(adc_read_con(qts, adc), ==,
                    CON_REFSEL | CON_MUX(index) | CON_EN);
            output = adc_read_data(qts, adc);
            g_assert_cmpuint(output, ==, expected_output);

            calibrated_voltage = adc_calibrate(output, expected_rv);
            g_assert_cmpuint(calibrated_voltage, >, input - MAX_ERROR);
            g_assert_cmpuint(calibrated_voltage, <, input + MAX_ERROR);
        }

        qtest_quit(qts);
    }
}

static void adc_add_test(const char *name, const ADC* wd,
        GTestDataFunc fn)
{
    g_autofree char *full_name = g_strdup_printf("npcm7xx_adc/%s",  name);
    qtest_add_data_func(full_name, wd, fn);
}
#define add_test(name, td) adc_add_test(#name, td, test_##name)

int main(int argc, char **argv)
{
    g_test_init(&argc, &argv, NULL);

    add_test(init, &adc_defs);
    add_test(convert_internal, &adc_defs);
    add_test(convert_external, &adc_defs);
    add_test(interrupt, &adc_defs);
    add_test(reset, &adc_defs);
    add_test(calibrate, &adc_defs);

    return g_test_run();
}
