/*
 * ARM dummy L210, L220, PL310 cache controller.
 *
 * Copyright (c) 2010-2012 Calxeda
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2 or any later version, as published by the Free Software
 * Foundation.
 *
 * This program is distributed in the hope 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 "sysbus.h"

/* L2C-310 r3p2 */
#define CACHE_ID 0x410000c8

typedef struct l2x0_state {
    SysBusDevice busdev;
    MemoryRegion iomem;
    uint32_t cache_type;
    uint32_t ctrl;
    uint32_t aux_ctrl;
    uint32_t data_ctrl;
    uint32_t tag_ctrl;
    uint32_t filter_start;
    uint32_t filter_end;
} l2x0_state;

static const VMStateDescription vmstate_l2x0 = {
    .name = "l2x0",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(ctrl, l2x0_state),
        VMSTATE_UINT32(aux_ctrl, l2x0_state),
        VMSTATE_UINT32(data_ctrl, l2x0_state),
        VMSTATE_UINT32(tag_ctrl, l2x0_state),
        VMSTATE_UINT32(filter_start, l2x0_state),
        VMSTATE_UINT32(filter_end, l2x0_state),
        VMSTATE_END_OF_LIST()
    }
};


static uint64_t l2x0_priv_read(void *opaque, hwaddr offset,
                               unsigned size)
{
    uint32_t cache_data;
    l2x0_state *s = (l2x0_state *)opaque;
    offset &= 0xfff;
    if (offset >= 0x730 && offset < 0x800) {
        return 0; /* cache ops complete */
    }
    switch (offset) {
    case 0:
        return CACHE_ID;
    case 0x4:
        /* aux_ctrl values affect cache_type values */
        cache_data = (s->aux_ctrl & (7 << 17)) >> 15;
        cache_data |= (s->aux_ctrl & (1 << 16)) >> 16;
        return s->cache_type |= (cache_data << 18) | (cache_data << 6);
    case 0x100:
        return s->ctrl;
    case 0x104:
        return s->aux_ctrl;
    case 0x108:
        return s->tag_ctrl;
    case 0x10C:
        return s->data_ctrl;
    case 0xC00:
        return s->filter_start;
    case 0xC04:
        return s->filter_end;
    case 0xF40:
        return 0;
    case 0xF60:
        return 0;
    case 0xF80:
        return 0;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "l2x0_priv_read: Bad offset %x\n", (int)offset);
        break;
    }
    return 0;
}

static void l2x0_priv_write(void *opaque, hwaddr offset,
                            uint64_t value, unsigned size)
{
    l2x0_state *s = (l2x0_state *)opaque;
    offset &= 0xfff;
    if (offset >= 0x730 && offset < 0x800) {
        /* ignore */
        return;
    }
    switch (offset) {
    case 0x100:
        s->ctrl = value & 1;
        break;
    case 0x104:
        s->aux_ctrl = value;
        break;
    case 0x108:
        s->tag_ctrl = value;
        break;
    case 0x10C:
        s->data_ctrl = value;
        break;
    case 0xC00:
        s->filter_start = value;
        break;
    case 0xC04:
        s->filter_end = value;
        break;
    case 0xF40:
        return;
    case 0xF60:
        return;
    case 0xF80:
        return;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "l2x0_priv_write: Bad offset %x\n", (int)offset);
        break;
    }
}

static void l2x0_priv_reset(DeviceState *dev)
{
    l2x0_state *s = DO_UPCAST(l2x0_state, busdev.qdev, dev);

    s->ctrl = 0;
    s->aux_ctrl = 0x02020000;
    s->tag_ctrl = 0;
    s->data_ctrl = 0;
    s->filter_start = 0;
    s->filter_end = 0;
}

static const MemoryRegionOps l2x0_mem_ops = {
    .read = l2x0_priv_read,
    .write = l2x0_priv_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
 };

static int l2x0_priv_init(SysBusDevice *dev)
{
    l2x0_state *s = FROM_SYSBUS(l2x0_state, dev);

    memory_region_init_io(&s->iomem, &l2x0_mem_ops, s, "l2x0_cc", 0x1000);
    sysbus_init_mmio(dev, &s->iomem);
    return 0;
}

static Property l2x0_properties[] = {
    DEFINE_PROP_UINT32("cache-type", l2x0_state, cache_type, 0x1c100100),
    DEFINE_PROP_END_OF_LIST(),
};

static void l2x0_class_init(ObjectClass *klass, void *data)
{
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
    DeviceClass *dc = DEVICE_CLASS(klass);

    k->init = l2x0_priv_init;
    dc->vmsd = &vmstate_l2x0;
    dc->no_user = 1;
    dc->props = l2x0_properties;
    dc->reset = l2x0_priv_reset;
}

static const TypeInfo l2x0_info = {
    .name = "l2x0",
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(l2x0_state),
    .class_init = l2x0_class_init,
};

static void l2x0_register_types(void)
{
    type_register_static(&l2x0_info);
}

type_init(l2x0_register_types)
