/*
 * STM32L4x5 GPIO (General Purpose Input/Ouput)
 *
 * Copyright (c) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
 * Copyright (c) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

/*
 * The reference used is the STMicroElectronics RM0351 Reference manual
 * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs.
 * https://www.st.com/en/microcontrollers-microprocessors/stm32l4x5/documentation.html
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "hw/gpio/stm32l4x5_gpio.h"
#include "hw/irq.h"
#include "hw/qdev-clock.h"
#include "hw/qdev-properties.h"
#include "qapi/visitor.h"
#include "qapi/error.h"
#include "migration/vmstate.h"
#include "trace.h"

#define GPIO_MODER 0x00
#define GPIO_OTYPER 0x04
#define GPIO_OSPEEDR 0x08
#define GPIO_PUPDR 0x0C
#define GPIO_IDR 0x10
#define GPIO_ODR 0x14
#define GPIO_BSRR 0x18
#define GPIO_LCKR 0x1C
#define GPIO_AFRL 0x20
#define GPIO_AFRH 0x24
#define GPIO_BRR 0x28
#define GPIO_ASCR 0x2C

/* 0b11111111_11111111_00000000_00000000 */
#define RESERVED_BITS_MASK 0xFFFF0000

static void update_gpio_idr(Stm32l4x5GpioState *s);

static bool is_pull_up(Stm32l4x5GpioState *s, unsigned pin)
{
    return extract32(s->pupdr, 2 * pin, 2) == 1;
}

static bool is_pull_down(Stm32l4x5GpioState *s, unsigned pin)
{
    return extract32(s->pupdr, 2 * pin, 2) == 2;
}

static bool is_output(Stm32l4x5GpioState *s, unsigned pin)
{
    return extract32(s->moder, 2 * pin, 2) == 1;
}

static bool is_open_drain(Stm32l4x5GpioState *s, unsigned pin)
{
    return extract32(s->otyper, pin, 1) == 1;
}

static bool is_push_pull(Stm32l4x5GpioState *s, unsigned pin)
{
    return extract32(s->otyper, pin, 1) == 0;
}

static void stm32l4x5_gpio_reset_hold(Object *obj, ResetType type)
{
    Stm32l4x5GpioState *s = STM32L4X5_GPIO(obj);

    s->moder = s->moder_reset;
    s->otyper = 0x00000000;
    s->ospeedr = s->ospeedr_reset;
    s->pupdr = s->pupdr_reset;
    s->idr = 0x00000000;
    s->odr = 0x00000000;
    s->lckr = 0x00000000;
    s->afrl = 0x00000000;
    s->afrh = 0x00000000;
    s->ascr = 0x00000000;

    s->disconnected_pins = 0xFFFF;
    s->pins_connected_high = 0x0000;
    update_gpio_idr(s);
}

static void stm32l4x5_gpio_set(void *opaque, int line, int level)
{
    Stm32l4x5GpioState *s = opaque;
    /*
     * The pin isn't set if line is configured in output mode
     * except if level is 0 and the output is open-drain.
     * This way there will be no short-circuit prone situations.
     */
    if (is_output(s, line) && !(is_open_drain(s, line) && (level == 0))) {
        qemu_log_mask(LOG_GUEST_ERROR, "Line %d can't be driven externally\n",
                      line);
        return;
    }

    s->disconnected_pins &= ~(1 << line);
    if (level) {
        s->pins_connected_high |= (1 << line);
    } else {
        s->pins_connected_high &= ~(1 << line);
    }
    trace_stm32l4x5_gpio_pins(s->name, s->disconnected_pins,
                              s->pins_connected_high);
    update_gpio_idr(s);
}


static void update_gpio_idr(Stm32l4x5GpioState *s)
{
    uint32_t new_idr_mask = 0;
    uint32_t new_idr = s->odr;
    uint32_t old_idr = s->idr;
    int new_pin_state, old_pin_state;

    for (int i = 0; i < GPIO_NUM_PINS; i++) {
        if (is_output(s, i)) {
            if (is_push_pull(s, i)) {
                new_idr_mask |= (1 << i);
            } else if (!(s->odr & (1 << i))) {
                /* open-drain ODR 0 */
                new_idr_mask |= (1 << i);
            /* open-drain ODR 1 */
            } else if (!(s->disconnected_pins & (1 << i)) &&
                       !(s->pins_connected_high & (1 << i))) {
                /* open-drain ODR 1 with pin connected low */
                new_idr_mask |= (1 << i);
                new_idr &= ~(1 << i);
            /* open-drain ODR 1 with unactive pin */
            } else if (is_pull_up(s, i)) {
                new_idr_mask |= (1 << i);
            } else if (is_pull_down(s, i)) {
                new_idr_mask |= (1 << i);
                new_idr &= ~(1 << i);
            }
            /*
             * The only case left is for open-drain ODR 1
             * with unactive pin without pull-up or pull-down :
             * the value is floating.
             */
        /* input or analog mode with connected pin */
        } else if (!(s->disconnected_pins & (1 << i))) {
            if (s->pins_connected_high & (1 << i)) {
                /* pin high */
                new_idr_mask |= (1 << i);
                new_idr |= (1 << i);
            } else {
                /* pin low */
                new_idr_mask |= (1 << i);
                new_idr &= ~(1 << i);
            }
        /* input or analog mode with disconnected pin */
        } else {
            if (is_pull_up(s, i)) {
                /* pull-up */
                new_idr_mask |= (1 << i);
                new_idr |= (1 << i);
            } else if (is_pull_down(s, i)) {
                /* pull-down */
                new_idr_mask |= (1 << i);
                new_idr &= ~(1 << i);
            }
            /*
             * The only case left is for a disconnected pin
             * without pull-up or pull-down :
             * the value is floating.
             */
        }
    }

    s->idr = (old_idr & ~new_idr_mask) | (new_idr & new_idr_mask);
    trace_stm32l4x5_gpio_update_idr(s->name, old_idr, s->idr);

    for (int i = 0; i < GPIO_NUM_PINS; i++) {
        if (new_idr_mask & (1 << i)) {
            new_pin_state = (new_idr & (1 << i)) > 0;
            old_pin_state = (old_idr & (1 << i)) > 0;
            if (new_pin_state > old_pin_state) {
                qemu_irq_raise(s->pin[i]);
            } else if (new_pin_state < old_pin_state) {
                qemu_irq_lower(s->pin[i]);
            }
        }
    }
}

/*
 * Return mask of pins that are both configured in output
 * mode and externally driven (except pins in open-drain
 * mode externally set to 0).
 */
static uint32_t get_gpio_pinmask_to_disconnect(Stm32l4x5GpioState *s)
{
    uint32_t pins_to_disconnect = 0;
    for (int i = 0; i < GPIO_NUM_PINS; i++) {
        /* for each connected pin in output mode */
        if (!(s->disconnected_pins & (1 << i)) && is_output(s, i)) {
            /* if either push-pull or high level */
            if (is_push_pull(s, i) || s->pins_connected_high & (1 << i)) {
                pins_to_disconnect |= (1 << i);
                qemu_log_mask(LOG_GUEST_ERROR,
                              "Line %d can't be driven externally\n",
                              i);
            }
        }
    }
    return pins_to_disconnect;
}

/*
 * Set field `disconnected_pins` and call `update_gpio_idr()`
 */
static void disconnect_gpio_pins(Stm32l4x5GpioState *s, uint16_t lines)
{
    s->disconnected_pins |= lines;
    trace_stm32l4x5_gpio_pins(s->name, s->disconnected_pins,
                              s->pins_connected_high);
    update_gpio_idr(s);
}

static void disconnected_pins_set(Object *obj, Visitor *v,
    const char *name, void *opaque, Error **errp)
{
    Stm32l4x5GpioState *s = STM32L4X5_GPIO(obj);
    uint16_t value;
    if (!visit_type_uint16(v, name, &value, errp)) {
        return;
    }
    disconnect_gpio_pins(s, value);
}

static void disconnected_pins_get(Object *obj, Visitor *v,
    const char *name, void *opaque, Error **errp)
{
    visit_type_uint16(v, name, (uint16_t *)opaque, errp);
}

static void clock_freq_get(Object *obj, Visitor *v,
    const char *name, void *opaque, Error **errp)
{
    Stm32l4x5GpioState *s = STM32L4X5_GPIO(obj);
    uint32_t clock_freq_hz = clock_get_hz(s->clk);
    visit_type_uint32(v, name, &clock_freq_hz, errp);
}

static void stm32l4x5_gpio_write(void *opaque, hwaddr addr,
                                 uint64_t val64, unsigned int size)
{
    Stm32l4x5GpioState *s = opaque;

    uint32_t value = val64;
    trace_stm32l4x5_gpio_write(s->name, addr, val64);

    switch (addr) {
    case GPIO_MODER:
        s->moder = value;
        disconnect_gpio_pins(s, get_gpio_pinmask_to_disconnect(s));
        qemu_log_mask(LOG_UNIMP,
                      "%s: Analog and AF modes aren't supported\n\
                       Analog and AF mode behave like input mode\n",
                      __func__);
        return;
    case GPIO_OTYPER:
        s->otyper = value & ~RESERVED_BITS_MASK;
        disconnect_gpio_pins(s, get_gpio_pinmask_to_disconnect(s));
        return;
    case GPIO_OSPEEDR:
        qemu_log_mask(LOG_UNIMP,
                      "%s: Changing I/O output speed isn't supported\n\
                       I/O speed is already maximal\n",
                      __func__);
        s->ospeedr = value;
        return;
    case GPIO_PUPDR:
        s->pupdr = value;
        update_gpio_idr(s);
        return;
    case GPIO_IDR:
        qemu_log_mask(LOG_UNIMP,
                      "%s: GPIO->IDR is read-only\n",
                      __func__);
        return;
    case GPIO_ODR:
        s->odr = value & ~RESERVED_BITS_MASK;
        update_gpio_idr(s);
        return;
    case GPIO_BSRR: {
        uint32_t bits_to_reset = (value & RESERVED_BITS_MASK) >> GPIO_NUM_PINS;
        uint32_t bits_to_set = value & ~RESERVED_BITS_MASK;
        /* If both BSx and BRx are set, BSx has priority.*/
        s->odr &= ~bits_to_reset;
        s->odr |= bits_to_set;
        update_gpio_idr(s);
        return;
    }
    case GPIO_LCKR:
        qemu_log_mask(LOG_UNIMP,
                      "%s: Locking port bits configuration isn't supported\n",
                      __func__);
        s->lckr = value & ~RESERVED_BITS_MASK;
        return;
    case GPIO_AFRL:
        qemu_log_mask(LOG_UNIMP,
                      "%s: Alternate functions aren't supported\n",
                      __func__);
        s->afrl = value;
        return;
    case GPIO_AFRH:
        qemu_log_mask(LOG_UNIMP,
                      "%s: Alternate functions aren't supported\n",
                      __func__);
        s->afrh = value;
        return;
    case GPIO_BRR: {
        uint32_t bits_to_reset = value & ~RESERVED_BITS_MASK;
        s->odr &= ~bits_to_reset;
        update_gpio_idr(s);
        return;
    }
    case GPIO_ASCR:
        qemu_log_mask(LOG_UNIMP,
                      "%s: ADC function isn't supported\n",
                      __func__);
        s->ascr = value & ~RESERVED_BITS_MASK;
        return;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, addr);
    }
}

static uint64_t stm32l4x5_gpio_read(void *opaque, hwaddr addr,
                                    unsigned int size)
{
    Stm32l4x5GpioState *s = opaque;

    trace_stm32l4x5_gpio_read(s->name, addr);

    switch (addr) {
    case GPIO_MODER:
        return s->moder;
    case GPIO_OTYPER:
        return s->otyper;
    case GPIO_OSPEEDR:
        return s->ospeedr;
    case GPIO_PUPDR:
        return s->pupdr;
    case GPIO_IDR:
        return s->idr;
    case GPIO_ODR:
        return s->odr;
    case GPIO_BSRR:
        return 0;
    case GPIO_LCKR:
        return s->lckr;
    case GPIO_AFRL:
        return s->afrl;
    case GPIO_AFRH:
        return s->afrh;
    case GPIO_BRR:
        return 0;
    case GPIO_ASCR:
        return s->ascr;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, addr);
        return 0;
    }
}

static const MemoryRegionOps stm32l4x5_gpio_ops = {
    .read = stm32l4x5_gpio_read,
    .write = stm32l4x5_gpio_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .impl = {
        .min_access_size = 4,
        .max_access_size = 4,
        .unaligned = false,
    },
    .valid = {
        .min_access_size = 4,
        .max_access_size = 4,
        .unaligned = false,
    },
};

static void stm32l4x5_gpio_init(Object *obj)
{
    Stm32l4x5GpioState *s = STM32L4X5_GPIO(obj);

    memory_region_init_io(&s->mmio, obj, &stm32l4x5_gpio_ops, s,
                          TYPE_STM32L4X5_GPIO, 0x400);

    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);

    qdev_init_gpio_out(DEVICE(obj), s->pin, GPIO_NUM_PINS);
    qdev_init_gpio_in(DEVICE(obj), stm32l4x5_gpio_set, GPIO_NUM_PINS);

    s->clk = qdev_init_clock_in(DEVICE(s), "clk", NULL, s, 0);

    object_property_add(obj, "disconnected-pins", "uint16",
                        disconnected_pins_get, disconnected_pins_set,
                        NULL, &s->disconnected_pins);
    object_property_add(obj, "clock-freq-hz", "uint32",
                        clock_freq_get, NULL, NULL, NULL);
}

static void stm32l4x5_gpio_realize(DeviceState *dev, Error **errp)
{
    Stm32l4x5GpioState *s = STM32L4X5_GPIO(dev);
    if (!clock_has_source(s->clk)) {
        error_setg(errp, "GPIO: clk input must be connected");
        return;
    }
}

static const VMStateDescription vmstate_stm32l4x5_gpio = {
    .name = TYPE_STM32L4X5_GPIO,
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]){
        VMSTATE_UINT32(moder, Stm32l4x5GpioState),
        VMSTATE_UINT32(otyper, Stm32l4x5GpioState),
        VMSTATE_UINT32(ospeedr, Stm32l4x5GpioState),
        VMSTATE_UINT32(pupdr, Stm32l4x5GpioState),
        VMSTATE_UINT32(idr, Stm32l4x5GpioState),
        VMSTATE_UINT32(odr, Stm32l4x5GpioState),
        VMSTATE_UINT32(lckr, Stm32l4x5GpioState),
        VMSTATE_UINT32(afrl, Stm32l4x5GpioState),
        VMSTATE_UINT32(afrh, Stm32l4x5GpioState),
        VMSTATE_UINT32(ascr, Stm32l4x5GpioState),
        VMSTATE_UINT16(disconnected_pins, Stm32l4x5GpioState),
        VMSTATE_UINT16(pins_connected_high, Stm32l4x5GpioState),
        VMSTATE_END_OF_LIST()
    }
};

static Property stm32l4x5_gpio_properties[] = {
    DEFINE_PROP_STRING("name", Stm32l4x5GpioState, name),
    DEFINE_PROP_UINT32("mode-reset", Stm32l4x5GpioState, moder_reset, 0),
    DEFINE_PROP_UINT32("ospeed-reset", Stm32l4x5GpioState, ospeedr_reset, 0),
    DEFINE_PROP_UINT32("pupd-reset", Stm32l4x5GpioState, pupdr_reset, 0),
    DEFINE_PROP_END_OF_LIST(),
};

static void stm32l4x5_gpio_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    ResettableClass *rc = RESETTABLE_CLASS(klass);

    device_class_set_props(dc, stm32l4x5_gpio_properties);
    dc->vmsd = &vmstate_stm32l4x5_gpio;
    dc->realize = stm32l4x5_gpio_realize;
    rc->phases.hold = stm32l4x5_gpio_reset_hold;
}

static const TypeInfo stm32l4x5_gpio_types[] = {
    {
        .name = TYPE_STM32L4X5_GPIO,
        .parent = TYPE_SYS_BUS_DEVICE,
        .instance_size = sizeof(Stm32l4x5GpioState),
        .instance_init = stm32l4x5_gpio_init,
        .class_init = stm32l4x5_gpio_class_init,
    },
};

DEFINE_TYPES(stm32l4x5_gpio_types)
