/*
 * i.MX USB PHY
 *
 * Copyright (c) 2020 Guenter Roeck <linux@roeck-us.net>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 *
 * We need to implement basic reset control in the PHY control register.
 * For everything else, it is sufficient to set whatever is written.
 */

#include "qemu/osdep.h"
#include "hw/usb/imx-usb-phy.h"
#include "migration/vmstate.h"
#include "qemu/log.h"
#include "qemu/module.h"

static const VMStateDescription vmstate_imx_usbphy = {
    .name = TYPE_IMX_USBPHY,
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32_ARRAY(usbphy, IMXUSBPHYState, USBPHY_MAX),
        VMSTATE_END_OF_LIST()
    },
};

static void imx_usbphy_softreset(IMXUSBPHYState *s)
{
    s->usbphy[USBPHY_PWD] = 0x001e1c00;
    s->usbphy[USBPHY_TX] = 0x10060607;
    s->usbphy[USBPHY_RX] = 0x00000000;
    s->usbphy[USBPHY_CTRL] = 0xc0200000;
}

static void imx_usbphy_reset(DeviceState *dev)
{
    IMXUSBPHYState *s = IMX_USBPHY(dev);

    s->usbphy[USBPHY_STATUS] = 0x00000000;
    s->usbphy[USBPHY_DEBUG] = 0x7f180000;
    s->usbphy[USBPHY_DEBUG0_STATUS] = 0x00000000;
    s->usbphy[USBPHY_DEBUG1] = 0x00001000;
    s->usbphy[USBPHY_VERSION] = 0x04020000;

    imx_usbphy_softreset(s);
}

static uint64_t imx_usbphy_read(void *opaque, hwaddr offset, unsigned size)
{
    IMXUSBPHYState *s = (IMXUSBPHYState *)opaque;
    uint32_t index = offset >> 2;
    uint32_t value;

    switch (index) {
    case USBPHY_PWD_SET:
    case USBPHY_TX_SET:
    case USBPHY_RX_SET:
    case USBPHY_CTRL_SET:
    case USBPHY_DEBUG_SET:
    case USBPHY_DEBUG1_SET:
        /*
         * All REG_NAME_SET register access are in fact targeting the
         * REG_NAME register.
         */
        value = s->usbphy[index - 1];
        break;
    case USBPHY_PWD_CLR:
    case USBPHY_TX_CLR:
    case USBPHY_RX_CLR:
    case USBPHY_CTRL_CLR:
    case USBPHY_DEBUG_CLR:
    case USBPHY_DEBUG1_CLR:
        /*
         * All REG_NAME_CLR register access are in fact targeting the
         * REG_NAME register.
         */
        value = s->usbphy[index - 2];
        break;
    case USBPHY_PWD_TOG:
    case USBPHY_TX_TOG:
    case USBPHY_RX_TOG:
    case USBPHY_CTRL_TOG:
    case USBPHY_DEBUG_TOG:
    case USBPHY_DEBUG1_TOG:
        /*
         * All REG_NAME_TOG register access are in fact targeting the
         * REG_NAME register.
         */
        value = s->usbphy[index - 3];
        break;
    default:
        value = s->usbphy[index];
        break;
    }
    return (uint64_t)value;
}

static void imx_usbphy_write(void *opaque, hwaddr offset, uint64_t value,
                             unsigned size)
{
    IMXUSBPHYState *s = (IMXUSBPHYState *)opaque;
    uint32_t index = offset >> 2;

    switch (index) {
    case USBPHY_CTRL:
        s->usbphy[index] = value;
        if (value & USBPHY_CTRL_SFTRST) {
            imx_usbphy_softreset(s);
        }
        break;
    case USBPHY_PWD:
    case USBPHY_TX:
    case USBPHY_RX:
    case USBPHY_STATUS:
    case USBPHY_DEBUG:
    case USBPHY_DEBUG1:
        s->usbphy[index] = value;
        break;
    case USBPHY_CTRL_SET:
        s->usbphy[index - 1] |= value;
        if (value & USBPHY_CTRL_SFTRST) {
            imx_usbphy_softreset(s);
        }
        break;
    case USBPHY_PWD_SET:
    case USBPHY_TX_SET:
    case USBPHY_RX_SET:
    case USBPHY_DEBUG_SET:
    case USBPHY_DEBUG1_SET:
        /*
         * All REG_NAME_SET register access are in fact targeting the
         * REG_NAME register. So we change the value of the REG_NAME
         * register, setting bits passed in the value.
         */
        s->usbphy[index - 1] |= value;
        break;
    case USBPHY_PWD_CLR:
    case USBPHY_TX_CLR:
    case USBPHY_RX_CLR:
    case USBPHY_CTRL_CLR:
    case USBPHY_DEBUG_CLR:
    case USBPHY_DEBUG1_CLR:
        /*
         * All REG_NAME_CLR register access are in fact targeting the
         * REG_NAME register. So we change the value of the REG_NAME
         * register, unsetting bits passed in the value.
         */
        s->usbphy[index - 2] &= ~value;
        break;
    case USBPHY_CTRL_TOG:
        s->usbphy[index - 3] ^= value;
        if ((value & USBPHY_CTRL_SFTRST) &&
            (s->usbphy[index - 3] & USBPHY_CTRL_SFTRST)) {
            imx_usbphy_softreset(s);
        }
        break;
    case USBPHY_PWD_TOG:
    case USBPHY_TX_TOG:
    case USBPHY_RX_TOG:
    case USBPHY_DEBUG_TOG:
    case USBPHY_DEBUG1_TOG:
        /*
         * All REG_NAME_TOG register access are in fact targeting the
         * REG_NAME register. So we change the value of the REG_NAME
         * register, toggling bits passed in the value.
         */
        s->usbphy[index - 3] ^= value;
        break;
    default:
        /* Other registers are read-only */
        break;
    }
}

static const struct MemoryRegionOps imx_usbphy_ops = {
    .read = imx_usbphy_read,
    .write = imx_usbphy_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid = {
        /*
         * Our device would not work correctly if the guest was doing
         * unaligned access. This might not be a limitation on the real
         * device but in practice there is no reason for a guest to access
         * this device unaligned.
         */
        .min_access_size = 4,
        .max_access_size = 4,
        .unaligned = false,
    },
};

static void imx_usbphy_realize(DeviceState *dev, Error **errp)
{
    IMXUSBPHYState *s = IMX_USBPHY(dev);

    memory_region_init_io(&s->iomem, OBJECT(s), &imx_usbphy_ops, s,
                          "imx-usbphy", 0x1000);
    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
}

static void imx_usbphy_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->reset = imx_usbphy_reset;
    dc->vmsd = &vmstate_imx_usbphy;
    dc->desc = "i.MX USB PHY Module";
    dc->realize = imx_usbphy_realize;
}

static const TypeInfo imx_usbphy_info = {
    .name          = TYPE_IMX_USBPHY,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(IMXUSBPHYState),
    .class_init    = imx_usbphy_class_init,
};

static void imx_usbphy_register_types(void)
{
    type_register_static(&imx_usbphy_info);
}

type_init(imx_usbphy_register_types)
