/*
 * Copyright (c) 2018, Impinj, Inc.
 *
 * Chipidea USB block emulation code
 *
 * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "hw/usb/hcd-ehci.h"
#include "hw/usb/chipidea.h"
#include "qemu/module.h"

enum {
    CHIPIDEA_USBx_DCIVERSION   = 0x000,
    CHIPIDEA_USBx_DCCPARAMS    = 0x004,
    CHIPIDEA_USBx_DCCPARAMS_HC = BIT(8),
};

static uint64_t chipidea_read(void *opaque, hwaddr offset,
                               unsigned size)
{
    return 0;
}

static void chipidea_write(void *opaque, hwaddr offset,
                            uint64_t value, unsigned size)
{
}

static const struct MemoryRegionOps chipidea_ops = {
    .read = chipidea_read,
    .write = chipidea_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .impl = {
        /*
         * 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 uint64_t chipidea_dc_read(void *opaque, hwaddr offset,
                                 unsigned size)
{
    switch (offset) {
    case CHIPIDEA_USBx_DCIVERSION:
        return 0x1;
    case CHIPIDEA_USBx_DCCPARAMS:
        /*
         * Real hardware (at least i.MX7) will also report the
         * controller as "Device Capable" (and 8 supported endpoints),
         * but there doesn't seem to be much point in doing so, since
         * we don't emulate that part.
         */
        return CHIPIDEA_USBx_DCCPARAMS_HC;
    }

    return 0;
}

static void chipidea_dc_write(void *opaque, hwaddr offset,
                              uint64_t value, unsigned size)
{
}

static const struct MemoryRegionOps chipidea_dc_ops = {
    .read = chipidea_dc_read,
    .write = chipidea_dc_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .impl = {
        /*
         * 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 chipidea_init(Object *obj)
{
    EHCIState *ehci = &SYS_BUS_EHCI(obj)->ehci;
    ChipideaState *ci = CHIPIDEA(obj);
    int i;

    for (i = 0; i < ARRAY_SIZE(ci->iomem); i++) {
        const struct {
            const char *name;
            hwaddr offset;
            uint64_t size;
            const struct MemoryRegionOps *ops;
        } regions[ARRAY_SIZE(ci->iomem)] = {
            /*
             * Registers located between offsets 0x000 and 0xFC
             */
            {
                .name   = TYPE_CHIPIDEA ".misc",
                .offset = 0x000,
                .size   = 0x100,
                .ops    = &chipidea_ops,
            },
            /*
             * Registers located between offsets 0x1A4 and 0x1DC
             */
            {
                .name   = TYPE_CHIPIDEA ".endpoints",
                .offset = 0x1A4,
                .size   = 0x1DC - 0x1A4 + 4,
                .ops    = &chipidea_ops,
            },
            /*
             * USB_x_DCIVERSION and USB_x_DCCPARAMS
             */
            {
                .name   = TYPE_CHIPIDEA ".dc",
                .offset = 0x120,
                .size   = 8,
                .ops    = &chipidea_dc_ops,
            },
        };

        memory_region_init_io(&ci->iomem[i],
                              obj,
                              regions[i].ops,
                              ci,
                              regions[i].name,
                              regions[i].size);

        memory_region_add_subregion(&ehci->mem,
                                    regions[i].offset,
                                    &ci->iomem[i]);
    }
}

static void chipidea_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(klass);

    /*
     * Offsets used were taken from i.MX7Dual Applications Processor
     * Reference Manual, Rev 0.1, p. 3177, Table 11-59
     */
    sec->capsbase   = 0x100;
    sec->opregbase  = 0x140;
    sec->portnr     = 1;

    set_bit(DEVICE_CATEGORY_USB, dc->categories);
    dc->desc = "Chipidea USB Module";
}

static const TypeInfo chipidea_info = {
    .name          = TYPE_CHIPIDEA,
    .parent        = TYPE_SYS_BUS_EHCI,
    .instance_size = sizeof(ChipideaState),
    .instance_init = chipidea_init,
    .class_init    = chipidea_class_init,
};

static void chipidea_register_type(void)
{
    type_register_static(&chipidea_info);
}
type_init(chipidea_register_type)
