/*
 * Allwinner R40 SRAM controller emulation
 *
 * Copyright (C) 2023 qianfan Zhao <qianfanguijin@163.com>
 *
 * 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 "qemu/units.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qapi/error.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "hw/misc/allwinner-sramc.h"
#include "trace.h"

/*
 * register offsets
 * https://linux-sunxi.org/SRAM_Controller_Register_Guide
 */
enum {
    REG_SRAM_CTL1_CFG               = 0x04, /* SRAM Control register 1 */
    REG_SRAM_VER                    = 0x24, /* SRAM Version register */
    REG_SRAM_R40_SOFT_ENTRY_REG0    = 0xbc,
};

/* REG_SRAMC_VERSION bit defines */
#define SRAM_VER_READ_ENABLE            (1 << 15)
#define SRAM_VER_VERSION_SHIFT          16
#define SRAM_VERSION_SUN8I_R40          0x1701

static uint64_t allwinner_sramc_read(void *opaque, hwaddr offset,
                                     unsigned size)
{
    AwSRAMCState *s = AW_SRAMC(opaque);
    AwSRAMCClass *sc = AW_SRAMC_GET_CLASS(s);
    uint64_t val = 0;

    switch (offset) {
    case REG_SRAM_CTL1_CFG:
        val = s->sram_ctl1;
        break;
    case REG_SRAM_VER:
        /* bit15: lock bit, set this bit before reading this register */
        if (s->sram_ver & SRAM_VER_READ_ENABLE) {
            val = SRAM_VER_READ_ENABLE |
                    (sc->sram_version_code << SRAM_VER_VERSION_SHIFT);
        }
        break;
    case REG_SRAM_R40_SOFT_ENTRY_REG0:
        val = s->sram_soft_entry_reg0;
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n",
                      __func__, (uint32_t)offset);
        return 0;
    }

    trace_allwinner_sramc_read(offset, val);

    return val;
}

static void allwinner_sramc_write(void *opaque, hwaddr offset,
                                  uint64_t val, unsigned size)
{
    AwSRAMCState *s = AW_SRAMC(opaque);

    trace_allwinner_sramc_write(offset, val);

    switch (offset) {
    case REG_SRAM_CTL1_CFG:
        s->sram_ctl1 = val;
        break;
    case REG_SRAM_VER:
        /* Only the READ_ENABLE bit is writeable */
        s->sram_ver = val & SRAM_VER_READ_ENABLE;
        break;
    case REG_SRAM_R40_SOFT_ENTRY_REG0:
        s->sram_soft_entry_reg0 = val;
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n",
                      __func__, (uint32_t)offset);
        break;
    }
}

static const MemoryRegionOps allwinner_sramc_ops = {
    .read = allwinner_sramc_read,
    .write = allwinner_sramc_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
    .impl.min_access_size = 4,
};

static const VMStateDescription allwinner_sramc_vmstate = {
    .name = "allwinner-sramc",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (const VMStateField[]) {
        VMSTATE_UINT32(sram_ver, AwSRAMCState),
        VMSTATE_UINT32(sram_soft_entry_reg0, AwSRAMCState),
        VMSTATE_END_OF_LIST()
    }
};

static void allwinner_sramc_reset(DeviceState *dev)
{
    AwSRAMCState *s = AW_SRAMC(dev);
    AwSRAMCClass *sc = AW_SRAMC_GET_CLASS(s);

    switch (sc->sram_version_code) {
    case SRAM_VERSION_SUN8I_R40:
        s->sram_ctl1 = 0x1300;
        break;
    }
}

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

    device_class_set_legacy_reset(dc, allwinner_sramc_reset);
    dc->vmsd = &allwinner_sramc_vmstate;
}

static void allwinner_sramc_init(Object *obj)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    AwSRAMCState *s = AW_SRAMC(obj);

    /* Memory mapping */
    memory_region_init_io(&s->iomem, OBJECT(s), &allwinner_sramc_ops, s,
                           TYPE_AW_SRAMC, 1 * KiB);
    sysbus_init_mmio(sbd, &s->iomem);
}

static const TypeInfo allwinner_sramc_info = {
    .name          = TYPE_AW_SRAMC,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_init = allwinner_sramc_init,
    .instance_size = sizeof(AwSRAMCState),
    .class_size    = sizeof(AwSRAMCClass),
    .class_init    = allwinner_sramc_class_init,
};

static void allwinner_r40_sramc_class_init(ObjectClass *klass, void *data)
{
    AwSRAMCClass *sc = AW_SRAMC_CLASS(klass);

    sc->sram_version_code = SRAM_VERSION_SUN8I_R40;
}

static const TypeInfo allwinner_r40_sramc_info = {
    .name          = TYPE_AW_SRAMC_SUN8I_R40,
    .parent        = TYPE_AW_SRAMC,
    .class_init    = allwinner_r40_sramc_class_init,
};

static void allwinner_sramc_register(void)
{
    type_register_static(&allwinner_sramc_info);
    type_register_static(&allwinner_r40_sramc_info);
}

type_init(allwinner_sramc_register)
