/*
 * Bananapi M2U 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 "exec/address-spaces.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "hw/boards.h"
#include "hw/i2c/i2c.h"
#include "hw/qdev-properties.h"
#include "hw/arm/allwinner-r40.h"

static struct arm_boot_info bpim2u_binfo;

/*
 * R40 can boot from mmc0 and mmc2, and bpim2u has two mmc interface, one is
 * connected to sdcard and another mount an emmc media.
 * Attach the mmc driver and try loading bootloader.
 */
static void mmc_attach_drive(AwR40State *s, AwSdHostState *mmc, int unit,
                             bool load_bootroom, bool *bootroom_loaded)
{
    DriveInfo *di = drive_get(IF_SD, 0, unit);
    BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
    BusState *bus;
    DeviceState *carddev;

    bus = qdev_get_child_bus(DEVICE(mmc), "sd-bus");
    if (bus == NULL) {
        error_report("No SD bus found in SOC object");
        exit(1);
    }

    carddev = qdev_new(TYPE_SD_CARD);
    qdev_prop_set_drive_err(carddev, "drive", blk, &error_fatal);
    qdev_realize_and_unref(carddev, bus, &error_fatal);

    if (load_bootroom && blk && blk_is_available(blk)) {
        /* Use Boot ROM to copy data from SD card to SRAM */
        *bootroom_loaded = allwinner_r40_bootrom_setup(s, blk, unit);
    }
}

static void bpim2u_init(MachineState *machine)
{
    bool bootroom_loaded = false;
    AwR40State *r40;
    I2CBus *i2c;

    /* BIOS is not supported by this board */
    if (machine->firmware) {
        error_report("BIOS not supported for this machine");
        exit(1);
    }

    /* Only allow Cortex-A7 for this board */
    if (strcmp(machine->cpu_type, ARM_CPU_TYPE_NAME("cortex-a7")) != 0) {
        error_report("This board can only be used with cortex-a7 CPU");
        exit(1);
    }

    r40 = AW_R40(object_new(TYPE_AW_R40));
    object_property_add_child(OBJECT(machine), "soc", OBJECT(r40));
    object_unref(OBJECT(r40));

    /* Setup timer properties */
    object_property_set_int(OBJECT(r40), "clk0-freq", 32768, &error_abort);
    object_property_set_int(OBJECT(r40), "clk1-freq", 24 * 1000 * 1000,
                            &error_abort);

    /* DRAMC */
    r40->ram_size = machine->ram_size / MiB;
    object_property_set_uint(OBJECT(r40), "ram-addr",
                             r40->memmap[AW_R40_DEV_SDRAM], &error_abort);
    object_property_set_int(OBJECT(r40), "ram-size",
                            r40->ram_size, &error_abort);

    /* GMAC PHY */
    object_property_set_uint(OBJECT(r40), "gmac-phy-addr", 1, &error_abort);

    /* Mark R40 object realized */
    qdev_realize(DEVICE(r40), NULL, &error_abort);

    /*
     * Plug in SD card and try load bootrom, R40 has 4 mmc controllers but can
     * only booting from mmc0 and mmc2.
     */
    for (int i = 0; i < AW_R40_NUM_MMCS; i++) {
        switch (i) {
        case 0:
        case 2:
            mmc_attach_drive(r40, &r40->mmc[i], i,
                             !machine->kernel_filename && !bootroom_loaded,
                             &bootroom_loaded);
            break;
        default:
            mmc_attach_drive(r40, &r40->mmc[i], i, false, NULL);
            break;
        }
    }

    /* Connect AXP221 */
    i2c = I2C_BUS(qdev_get_child_bus(DEVICE(&r40->i2c0), "i2c"));
    i2c_slave_create_simple(i2c, "axp221_pmu", 0x34);

    /* SDRAM */
    memory_region_add_subregion(get_system_memory(),
                                r40->memmap[AW_R40_DEV_SDRAM], machine->ram);

    bpim2u_binfo.loader_start = r40->memmap[AW_R40_DEV_SDRAM];
    bpim2u_binfo.ram_size = machine->ram_size;
    bpim2u_binfo.psci_conduit = QEMU_PSCI_CONDUIT_SMC;
    arm_load_kernel(ARM_CPU(first_cpu), machine, &bpim2u_binfo);
}

static void bpim2u_machine_init(MachineClass *mc)
{
    mc->desc = "Bananapi M2U (Cortex-A7)";
    mc->init = bpim2u_init;
    mc->min_cpus = AW_R40_NUM_CPUS;
    mc->max_cpus = AW_R40_NUM_CPUS;
    mc->default_cpus = AW_R40_NUM_CPUS;
    mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a7");
    mc->default_ram_size = 1 * GiB;
    mc->default_ram_id = "bpim2u.ram";
}

DEFINE_MACHINE("bpim2u", bpim2u_machine_init)
