/*
 * Allwinner A10 Clock Control Module emulation
 *
 * Copyright (C) 2022 Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
 *
 *  This file is derived from Allwinner H3 CCU,
 *  by Niek Linnenbank.
 *
 * 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 "hw/misc/allwinner-a10-ccm.h"

/* CCM register offsets */
enum {
    REG_PLL1_CFG             = 0x0000, /* PLL1 Control */
    REG_PLL1_TUN             = 0x0004, /* PLL1 Tuning */
    REG_PLL2_CFG             = 0x0008, /* PLL2 Control */
    REG_PLL2_TUN             = 0x000C, /* PLL2 Tuning */
    REG_PLL3_CFG             = 0x0010, /* PLL3 Control */
    REG_PLL4_CFG             = 0x0018, /* PLL4 Control */
    REG_PLL5_CFG             = 0x0020, /* PLL5 Control */
    REG_PLL5_TUN             = 0x0024, /* PLL5 Tuning */
    REG_PLL6_CFG             = 0x0028, /* PLL6 Control */
    REG_PLL6_TUN             = 0x002C, /* PLL6 Tuning */
    REG_PLL7_CFG             = 0x0030, /* PLL7 Control */
    REG_PLL1_TUN2            = 0x0038, /* PLL1 Tuning2 */
    REG_PLL5_TUN2            = 0x003C, /* PLL5 Tuning2 */
    REG_PLL8_CFG             = 0x0040, /* PLL8 Control */
    REG_OSC24M_CFG           = 0x0050, /* OSC24M Control */
    REG_CPU_AHB_APB0_CFG     = 0x0054, /* CPU, AHB and APB0 Divide Ratio */
};

#define REG_INDEX(offset)    (offset / sizeof(uint32_t))

/* CCM register reset values */
enum {
    REG_PLL1_CFG_RST         = 0x21005000,
    REG_PLL1_TUN_RST         = 0x0A101000,
    REG_PLL2_CFG_RST         = 0x08100010,
    REG_PLL2_TUN_RST         = 0x00000000,
    REG_PLL3_CFG_RST         = 0x0010D063,
    REG_PLL4_CFG_RST         = 0x21009911,
    REG_PLL5_CFG_RST         = 0x11049280,
    REG_PLL5_TUN_RST         = 0x14888000,
    REG_PLL6_CFG_RST         = 0x21009911,
    REG_PLL6_TUN_RST         = 0x00000000,
    REG_PLL7_CFG_RST         = 0x0010D063,
    REG_PLL1_TUN2_RST        = 0x00000000,
    REG_PLL5_TUN2_RST        = 0x00000000,
    REG_PLL8_CFG_RST         = 0x21009911,
    REG_OSC24M_CFG_RST       = 0x00138013,
    REG_CPU_AHB_APB0_CFG_RST = 0x00010010,
};

static uint64_t allwinner_a10_ccm_read(void *opaque, hwaddr offset,
                                       unsigned size)
{
    const AwA10ClockCtlState *s = AW_A10_CCM(opaque);
    const uint32_t idx = REG_INDEX(offset);

    switch (offset) {
    case REG_PLL1_CFG:
    case REG_PLL1_TUN:
    case REG_PLL2_CFG:
    case REG_PLL2_TUN:
    case REG_PLL3_CFG:
    case REG_PLL4_CFG:
    case REG_PLL5_CFG:
    case REG_PLL5_TUN:
    case REG_PLL6_CFG:
    case REG_PLL6_TUN:
    case REG_PLL7_CFG:
    case REG_PLL1_TUN2:
    case REG_PLL5_TUN2:
    case REG_PLL8_CFG:
    case REG_OSC24M_CFG:
    case REG_CPU_AHB_APB0_CFG:
        break;
    case 0x158 ... AW_A10_CCM_IOSIZE:
        qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n",
                      __func__, (uint32_t)offset);
        return 0;
    default:
        qemu_log_mask(LOG_UNIMP, "%s: unimplemented read offset 0x%04x\n",
                      __func__, (uint32_t)offset);
        return 0;
    }

    return s->regs[idx];
}

static void allwinner_a10_ccm_write(void *opaque, hwaddr offset,
                                   uint64_t val, unsigned size)
{
    AwA10ClockCtlState *s = AW_A10_CCM(opaque);
    const uint32_t idx = REG_INDEX(offset);

    switch (offset) {
    case REG_PLL1_CFG:
    case REG_PLL1_TUN:
    case REG_PLL2_CFG:
    case REG_PLL2_TUN:
    case REG_PLL3_CFG:
    case REG_PLL4_CFG:
    case REG_PLL5_CFG:
    case REG_PLL5_TUN:
    case REG_PLL6_CFG:
    case REG_PLL6_TUN:
    case REG_PLL7_CFG:
    case REG_PLL1_TUN2:
    case REG_PLL5_TUN2:
    case REG_PLL8_CFG:
    case REG_OSC24M_CFG:
    case REG_CPU_AHB_APB0_CFG:
        break;
    case 0x158 ... AW_A10_CCM_IOSIZE:
        qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n",
                      __func__, (uint32_t)offset);
        break;
    default:
        qemu_log_mask(LOG_UNIMP, "%s: unimplemented write offset 0x%04x\n",
                      __func__, (uint32_t)offset);
        break;
    }

    s->regs[idx] = (uint32_t) val;
}

static const MemoryRegionOps allwinner_a10_ccm_ops = {
    .read = allwinner_a10_ccm_read,
    .write = allwinner_a10_ccm_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
    .impl.min_access_size = 4,
};

static void allwinner_a10_ccm_reset_enter(Object *obj, ResetType type)
{
    AwA10ClockCtlState *s = AW_A10_CCM(obj);

    /* Set default values for registers */
    s->regs[REG_INDEX(REG_PLL1_CFG)] = REG_PLL1_CFG_RST;
    s->regs[REG_INDEX(REG_PLL1_TUN)] = REG_PLL1_TUN_RST;
    s->regs[REG_INDEX(REG_PLL2_CFG)] = REG_PLL2_CFG_RST;
    s->regs[REG_INDEX(REG_PLL2_TUN)] = REG_PLL2_TUN_RST;
    s->regs[REG_INDEX(REG_PLL3_CFG)] = REG_PLL3_CFG_RST;
    s->regs[REG_INDEX(REG_PLL4_CFG)] = REG_PLL4_CFG_RST;
    s->regs[REG_INDEX(REG_PLL5_CFG)] = REG_PLL5_CFG_RST;
    s->regs[REG_INDEX(REG_PLL5_TUN)] = REG_PLL5_TUN_RST;
    s->regs[REG_INDEX(REG_PLL6_CFG)] = REG_PLL6_CFG_RST;
    s->regs[REG_INDEX(REG_PLL6_TUN)] = REG_PLL6_TUN_RST;
    s->regs[REG_INDEX(REG_PLL7_CFG)] = REG_PLL7_CFG_RST;
    s->regs[REG_INDEX(REG_PLL1_TUN2)] = REG_PLL1_TUN2_RST;
    s->regs[REG_INDEX(REG_PLL5_TUN2)] = REG_PLL5_TUN2_RST;
    s->regs[REG_INDEX(REG_PLL8_CFG)] = REG_PLL8_CFG_RST;
    s->regs[REG_INDEX(REG_OSC24M_CFG)] = REG_OSC24M_CFG_RST;
    s->regs[REG_INDEX(REG_CPU_AHB_APB0_CFG)] = REG_CPU_AHB_APB0_CFG_RST;
}

static void allwinner_a10_ccm_init(Object *obj)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    AwA10ClockCtlState *s = AW_A10_CCM(obj);

    /* Memory mapping */
    memory_region_init_io(&s->iomem, OBJECT(s), &allwinner_a10_ccm_ops, s,
                          TYPE_AW_A10_CCM, AW_A10_CCM_IOSIZE);
    sysbus_init_mmio(sbd, &s->iomem);
}

static const VMStateDescription allwinner_a10_ccm_vmstate = {
    .name = "allwinner-a10-ccm",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32_ARRAY(regs, AwA10ClockCtlState, AW_A10_CCM_REGS_NUM),
        VMSTATE_END_OF_LIST()
    }
};

static void allwinner_a10_ccm_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    ResettableClass *rc = RESETTABLE_CLASS(klass);

    rc->phases.enter = allwinner_a10_ccm_reset_enter;
    dc->vmsd = &allwinner_a10_ccm_vmstate;
}

static const TypeInfo allwinner_a10_ccm_info = {
    .name          = TYPE_AW_A10_CCM,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_init = allwinner_a10_ccm_init,
    .instance_size = sizeof(AwA10ClockCtlState),
    .class_init    = allwinner_a10_ccm_class_init,
};

static void allwinner_a10_ccm_register(void)
{
    type_register_static(&allwinner_a10_ccm_info);
}

type_init(allwinner_a10_ccm_register)
