/*
 * QEMU Allwinner AHCI Emulation
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "hw/hw.h"
#include "qemu/error-report.h"
#include "sysemu/block-backend.h"
#include "sysemu/dma.h"
#include "hw/ide/internal.h"
#include "hw/ide/ahci_internal.h"

#include "trace.h"

#define ALLWINNER_AHCI_BISTAFR    ((0xa0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_BISTCR     ((0xa4 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_BISTFCTR   ((0xa8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_BISTSR     ((0xac - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_BISTDECR   ((0xb0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_DIAGNR0    ((0xb4 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_DIAGNR1    ((0xb8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_OOBR       ((0xbc - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_PHYCS0R    ((0xc0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_PHYCS1R    ((0xc4 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_PHYCS2R    ((0xc8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_TIMER1MS   ((0xe0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_GPARAM1R   ((0xe8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_GPARAM2R   ((0xec - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_PPARAMR    ((0xf0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_TESTR      ((0xf4 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_VERSIONR   ((0xf8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_IDR        ((0xfc - ALLWINNER_AHCI_MMIO_OFF) / 4)
#define ALLWINNER_AHCI_RWCR       ((0xfc - ALLWINNER_AHCI_MMIO_OFF) / 4)

static uint64_t allwinner_ahci_mem_read(void *opaque, hwaddr addr,
                                        unsigned size)
{
    AllwinnerAHCIState *a = opaque;
    AHCIState *s = &(SYSBUS_AHCI(a)->ahci);
    uint64_t val = a->regs[addr / 4];

    switch (addr / 4) {
    case ALLWINNER_AHCI_PHYCS0R:
        val |= 0x2 << 28;
        break;
    case ALLWINNER_AHCI_PHYCS2R:
        val &= ~(0x1 << 24);
        break;
    }
    trace_allwinner_ahci_mem_read(s, a, addr, val, size);
    return  val;
}

static void allwinner_ahci_mem_write(void *opaque, hwaddr addr,
                                     uint64_t val, unsigned size)
{
    AllwinnerAHCIState *a = opaque;
    AHCIState *s = &(SYSBUS_AHCI(a)->ahci);

    trace_allwinner_ahci_mem_write(s, a, addr, val, size);
    a->regs[addr / 4] = val;
}

static const MemoryRegionOps allwinner_ahci_mem_ops = {
    .read = allwinner_ahci_mem_read,
    .write = allwinner_ahci_mem_write,
    .valid.min_access_size = 4,
    .valid.max_access_size = 4,
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static void allwinner_ahci_init(Object *obj)
{
    SysbusAHCIState *s = SYSBUS_AHCI(obj);
    AllwinnerAHCIState *a = ALLWINNER_AHCI(obj);

    memory_region_init_io(&a->mmio, OBJECT(obj), &allwinner_ahci_mem_ops, a,
                          "allwinner-ahci", ALLWINNER_AHCI_MMIO_SIZE);
    memory_region_add_subregion(&s->ahci.mem, ALLWINNER_AHCI_MMIO_OFF,
                                &a->mmio);
}

static const VMStateDescription vmstate_allwinner_ahci = {
    .name = "allwinner-ahci",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32_ARRAY(regs, AllwinnerAHCIState,
                             ALLWINNER_AHCI_MMIO_SIZE / 4),
        VMSTATE_END_OF_LIST()
    }
};

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

    dc->vmsd = &vmstate_allwinner_ahci;
}

static const TypeInfo allwinner_ahci_info = {
    .name          = TYPE_ALLWINNER_AHCI,
    .parent        = TYPE_SYSBUS_AHCI,
    .instance_size = sizeof(AllwinnerAHCIState),
    .instance_init = allwinner_ahci_init,
    .class_init    = allwinner_ahci_class_init,
};

static void sysbus_ahci_register_types(void)
{
    type_register_static(&allwinner_ahci_info);
}

type_init(sysbus_ahci_register_types)
