/*
 * QEMU PowerPC 4xx embedded processors SDRAM controller emulation
 *
 * DDR SDRAM controller:
 * Copyright (c) 2007 Jocelyn Mayer
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * DDR2 SDRAM controller:
 * Copyright (c) 2012 François Revol
 * Copyright (c) 2016-2019 BALATON Zoltan
 *
 * This work is licensed under the GNU GPL license version 2 or later.
 */

#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "qemu/log.h"
#include "exec/address-spaces.h" /* get_system_memory() */
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "hw/ppc/ppc4xx.h"
#include "trace.h"

/*****************************************************************************/
/* Shared functions */

/*
 * Split RAM between SDRAM banks.
 *
 * sdram_bank_sizes[] must be in descending order, that is sizes[i] > sizes[i+1]
 * and must be 0-terminated.
 *
 * The 4xx SDRAM controller supports a small number of banks, and each bank
 * must be one of a small set of sizes. The number of banks and the supported
 * sizes varies by SoC.
 */
static bool ppc4xx_sdram_banks(MemoryRegion *ram, int nr_banks,
                               Ppc4xxSdramBank ram_banks[],
                               const ram_addr_t sdram_bank_sizes[],
                               Error **errp)
{
    ERRP_GUARD();
    ram_addr_t size_left = memory_region_size(ram);
    ram_addr_t base = 0;
    ram_addr_t bank_size;
    int i;
    int j;

    for (i = 0; i < nr_banks; i++) {
        for (j = 0; sdram_bank_sizes[j] != 0; j++) {
            bank_size = sdram_bank_sizes[j];
            if (bank_size <= size_left) {
                char name[32];

                ram_banks[i].base = base;
                ram_banks[i].size = bank_size;
                base += bank_size;
                size_left -= bank_size;
                snprintf(name, sizeof(name), "ppc4xx.sdram%d", i);
                memory_region_init_alias(&ram_banks[i].ram, NULL, name, ram,
                                         ram_banks[i].base, ram_banks[i].size);
                break;
            }
        }
        if (!size_left) {
            /* No need to use the remaining banks. */
            break;
        }
    }

    if (size_left) {
        ram_addr_t used_size = memory_region_size(ram) - size_left;
        GString *s = g_string_new(NULL);

        for (i = 0; sdram_bank_sizes[i]; i++) {
            g_string_append_printf(s, "%" PRIi64 "%s",
                                   sdram_bank_sizes[i] / MiB,
                                   sdram_bank_sizes[i + 1] ? ", " : "");
        }
        error_setg(errp, "Invalid SDRAM banks");
        error_append_hint(errp, "at most %d bank%s of %s MiB each supported\n",
                          nr_banks, nr_banks == 1 ? "" : "s", s->str);
        error_append_hint(errp, "Possible valid RAM size: %" PRIi64 " MiB\n",
                  used_size ? used_size / MiB : sdram_bank_sizes[i - 1] / MiB);

        g_string_free(s, true);
        return false;
    }
    return true;
}

static void sdram_bank_map(Ppc4xxSdramBank *bank)
{
    trace_ppc4xx_sdram_map(bank->base, bank->size);
    memory_region_init(&bank->container, NULL, "sdram-container", bank->size);
    memory_region_add_subregion(&bank->container, 0, &bank->ram);
    memory_region_add_subregion(get_system_memory(), bank->base,
                                &bank->container);
}

static void sdram_bank_unmap(Ppc4xxSdramBank *bank)
{
    trace_ppc4xx_sdram_unmap(bank->base, bank->size);
    memory_region_del_subregion(get_system_memory(), &bank->container);
    memory_region_del_subregion(&bank->container, &bank->ram);
    object_unparent(OBJECT(&bank->container));
}

static void sdram_bank_set_bcr(Ppc4xxSdramBank *bank, uint32_t bcr,
                               hwaddr base, hwaddr size, int enabled)
{
    if (memory_region_is_mapped(&bank->container)) {
        sdram_bank_unmap(bank);
    }
    bank->bcr = bcr;
    bank->base = base;
    bank->size = size;
    if (enabled && (bcr & 1)) {
        sdram_bank_map(bank);
    }
}

enum {
    SDRAM0_CFGADDR = 0x010,
    SDRAM0_CFGDATA = 0x011,
};

/*****************************************************************************/
/* DDR SDRAM controller */
#define SDRAM_DDR_BCR_MASK 0xFFDEE001

static uint32_t sdram_ddr_bcr(hwaddr ram_base, hwaddr ram_size)
{
    uint32_t bcr;

    switch (ram_size) {
    case 4 * MiB:
        bcr = 0;
        break;
    case 8 * MiB:
        bcr = 0x20000;
        break;
    case 16 * MiB:
        bcr = 0x40000;
        break;
    case 32 * MiB:
        bcr = 0x60000;
        break;
    case 64 * MiB:
        bcr = 0x80000;
        break;
    case 128 * MiB:
        bcr = 0xA0000;
        break;
    case 256 * MiB:
        bcr = 0xC0000;
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: invalid RAM size 0x%" HWADDR_PRIx "\n", __func__,
                      ram_size);
        return 0;
    }
    bcr |= ram_base & 0xFF800000;
    bcr |= 1;

    return bcr;
}

static inline hwaddr sdram_ddr_base(uint32_t bcr)
{
    return bcr & 0xFF800000;
}

static hwaddr sdram_ddr_size(uint32_t bcr)
{
    int sh = (bcr >> 17) & 0x7;

    if (sh == 7) {
        return -1;
    }

    return (4 * MiB) << sh;
}

static uint32_t sdram_ddr_dcr_read(void *opaque, int dcrn)
{
    Ppc4xxSdramDdrState *s = opaque;
    uint32_t ret;

    switch (dcrn) {
    case SDRAM0_CFGADDR:
        ret = s->addr;
        break;
    case SDRAM0_CFGDATA:
        switch (s->addr) {
        case 0x00: /* SDRAM_BESR0 */
            ret = s->besr0;
            break;
        case 0x08: /* SDRAM_BESR1 */
            ret = s->besr1;
            break;
        case 0x10: /* SDRAM_BEAR */
            ret = s->bear;
            break;
        case 0x20: /* SDRAM_CFG */
            ret = s->cfg;
            break;
        case 0x24: /* SDRAM_STATUS */
            ret = s->status;
            break;
        case 0x30: /* SDRAM_RTR */
            ret = s->rtr;
            break;
        case 0x34: /* SDRAM_PMIT */
            ret = s->pmit;
            break;
        case 0x40: /* SDRAM_B0CR */
            ret = s->bank[0].bcr;
            break;
        case 0x44: /* SDRAM_B1CR */
            ret = s->bank[1].bcr;
            break;
        case 0x48: /* SDRAM_B2CR */
            ret = s->bank[2].bcr;
            break;
        case 0x4C: /* SDRAM_B3CR */
            ret = s->bank[3].bcr;
            break;
        case 0x80: /* SDRAM_TR */
            ret = -1; /* ? */
            break;
        case 0x94: /* SDRAM_ECCCFG */
            ret = s->ecccfg;
            break;
        case 0x98: /* SDRAM_ECCESR */
            ret = s->eccesr;
            break;
        default: /* Error */
            ret = -1;
            break;
        }
        break;
    default:
        /* Avoid gcc warning */
        ret = 0;
        break;
    }

    return ret;
}

static void sdram_ddr_dcr_write(void *opaque, int dcrn, uint32_t val)
{
    Ppc4xxSdramDdrState *s = opaque;
    int i;

    switch (dcrn) {
    case SDRAM0_CFGADDR:
        s->addr = val;
        break;
    case SDRAM0_CFGDATA:
        switch (s->addr) {
        case 0x00: /* SDRAM_BESR0 */
            s->besr0 &= ~val;
            break;
        case 0x08: /* SDRAM_BESR1 */
            s->besr1 &= ~val;
            break;
        case 0x10: /* SDRAM_BEAR */
            s->bear = val;
            break;
        case 0x20: /* SDRAM_CFG */
            val &= 0xFFE00000;
            if (!(s->cfg & 0x80000000) && (val & 0x80000000)) {
                trace_ppc4xx_sdram_enable("enable");
                /* validate all RAM mappings */
                for (i = 0; i < s->nbanks; i++) {
                    if (s->bank[i].size) {
                        sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr,
                                           s->bank[i].base, s->bank[i].size,
                                           1);
                    }
                }
                s->status &= ~0x80000000;
            } else if ((s->cfg & 0x80000000) && !(val & 0x80000000)) {
                trace_ppc4xx_sdram_enable("disable");
                /* invalidate all RAM mappings */
                for (i = 0; i < s->nbanks; i++) {
                    if (s->bank[i].size) {
                        sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr,
                                           s->bank[i].base, s->bank[i].size,
                                           0);
                    }
                }
                s->status |= 0x80000000;
            }
            if (!(s->cfg & 0x40000000) && (val & 0x40000000)) {
                s->status |= 0x40000000;
            } else if ((s->cfg & 0x40000000) && !(val & 0x40000000)) {
                s->status &= ~0x40000000;
            }
            s->cfg = val;
            break;
        case 0x24: /* SDRAM_STATUS */
            /* Read-only register */
            break;
        case 0x30: /* SDRAM_RTR */
            s->rtr = val & 0x3FF80000;
            break;
        case 0x34: /* SDRAM_PMIT */
            s->pmit = (val & 0xF8000000) | 0x07C00000;
            break;
        case 0x40: /* SDRAM_B0CR */
        case 0x44: /* SDRAM_B1CR */
        case 0x48: /* SDRAM_B2CR */
        case 0x4C: /* SDRAM_B3CR */
            i = (s->addr - 0x40) / 4;
            val &= SDRAM_DDR_BCR_MASK;
            if (s->bank[i].size) {
                sdram_bank_set_bcr(&s->bank[i], val,
                                   sdram_ddr_base(val), sdram_ddr_size(val),
                                   s->cfg & 0x80000000);
            }
            break;
        case 0x80: /* SDRAM_TR */
            s->tr = val & 0x018FC01F;
            break;
        case 0x94: /* SDRAM_ECCCFG */
            s->ecccfg = val & 0x00F00000;
            break;
        case 0x98: /* SDRAM_ECCESR */
            val &= 0xFFF0F000;
            if (s->eccesr == 0 && val != 0) {
                qemu_irq_raise(s->irq);
            } else if (s->eccesr != 0 && val == 0) {
                qemu_irq_lower(s->irq);
            }
            s->eccesr = val;
            break;
        default: /* Error */
            break;
        }
        break;
    }
}

static void ppc4xx_sdram_ddr_reset(DeviceState *dev)
{
    Ppc4xxSdramDdrState *s = PPC4xx_SDRAM_DDR(dev);

    s->addr = 0;
    s->bear = 0;
    s->besr0 = 0; /* No error */
    s->besr1 = 0; /* No error */
    s->cfg = 0;
    s->ecccfg = 0; /* No ECC */
    s->eccesr = 0; /* No error */
    s->pmit = 0x07C00000;
    s->rtr = 0x05F00000;
    s->tr = 0x00854009;
    /* We pre-initialize RAM banks */
    s->status = 0;
    s->cfg = 0x00800000;
}

static void ppc4xx_sdram_ddr_realize(DeviceState *dev, Error **errp)
{
    Ppc4xxSdramDdrState *s = PPC4xx_SDRAM_DDR(dev);
    Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev);
    const ram_addr_t valid_bank_sizes[] = {
        256 * MiB, 128 * MiB, 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 4 * MiB, 0
    };
    int i;

    if (s->nbanks < 1 || s->nbanks > 4) {
        error_setg(errp, "Invalid number of RAM banks");
        return;
    }
    if (!s->dram_mr) {
        error_setg(errp, "Missing dram memory region");
        return;
    }
    if (!ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank,
                            valid_bank_sizes, errp)) {
        return;
    }
    for (i = 0; i < s->nbanks; i++) {
        if (s->bank[i].size) {
            s->bank[i].bcr = sdram_ddr_bcr(s->bank[i].base, s->bank[i].size);
            sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr,
                               s->bank[i].base, s->bank[i].size, 0);
        } else {
            sdram_bank_set_bcr(&s->bank[i], 0, 0, 0, 0);
        }
        trace_ppc4xx_sdram_init(sdram_ddr_base(s->bank[i].bcr),
                                sdram_ddr_size(s->bank[i].bcr),
                                s->bank[i].bcr);
    }

    sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);

    ppc4xx_dcr_register(dcr, SDRAM0_CFGADDR,
                        s, &sdram_ddr_dcr_read, &sdram_ddr_dcr_write);
    ppc4xx_dcr_register(dcr, SDRAM0_CFGDATA,
                        s, &sdram_ddr_dcr_read, &sdram_ddr_dcr_write);
}

static Property ppc4xx_sdram_ddr_props[] = {
    DEFINE_PROP_LINK("dram", Ppc4xxSdramDdrState, dram_mr, TYPE_MEMORY_REGION,
                     MemoryRegion *),
    DEFINE_PROP_UINT32("nbanks", Ppc4xxSdramDdrState, nbanks, 4),
    DEFINE_PROP_END_OF_LIST(),
};

static void ppc4xx_sdram_ddr_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);

    dc->realize = ppc4xx_sdram_ddr_realize;
    dc->reset = ppc4xx_sdram_ddr_reset;
    /* Reason: only works as function of a ppc4xx SoC */
    dc->user_creatable = false;
    device_class_set_props(dc, ppc4xx_sdram_ddr_props);
}

void ppc4xx_sdram_ddr_enable(Ppc4xxSdramDdrState *s)
{
    sdram_ddr_dcr_write(s, SDRAM0_CFGADDR, 0x20);
    sdram_ddr_dcr_write(s, SDRAM0_CFGDATA, 0x80000000);
}

/*****************************************************************************/
/* DDR2 SDRAM controller */
#define SDRAM_DDR2_BCR_MASK 0xffe0ffc1

enum {
    SDRAM_R0BAS = 0x40,
    SDRAM_R1BAS,
    SDRAM_R2BAS,
    SDRAM_R3BAS,
    SDRAM_CONF1HB = 0x45,
    SDRAM_PLBADDULL = 0x4a,
    SDRAM_CONF1LL = 0x4b,
    SDRAM_CONFPATHB = 0x4f,
    SDRAM_PLBADDUHB = 0x50,
};

static uint32_t sdram_ddr2_bcr(hwaddr ram_base, hwaddr ram_size)
{
    uint32_t bcr;

    switch (ram_size) {
    case 8 * MiB:
        bcr = 0xffc0;
        break;
    case 16 * MiB:
        bcr = 0xff80;
        break;
    case 32 * MiB:
        bcr = 0xff00;
        break;
    case 64 * MiB:
        bcr = 0xfe00;
        break;
    case 128 * MiB:
        bcr = 0xfc00;
        break;
    case 256 * MiB:
        bcr = 0xf800;
        break;
    case 512 * MiB:
        bcr = 0xf000;
        break;
    case 1 * GiB:
        bcr = 0xe000;
        break;
    case 2 * GiB:
        bcr = 0xc000;
        break;
    case 4 * GiB:
        bcr = 0x8000;
        break;
    default:
        error_report("invalid RAM size " HWADDR_FMT_plx, ram_size);
        return 0;
    }
    bcr |= ram_base >> 2 & 0xffe00000;
    bcr |= 1;

    return bcr;
}

static inline hwaddr sdram_ddr2_base(uint32_t bcr)
{
    return (bcr & 0xffe00000) << 2;
}

static hwaddr sdram_ddr2_size(uint32_t bcr)
{
    int sh;

    sh = 1024 - ((bcr >> 6) & 0x3ff);
    return 8 * MiB * sh;
}

static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn)
{
    Ppc4xxSdramDdr2State *s = opaque;
    uint32_t ret = 0;

    switch (dcrn) {
    case SDRAM_R0BAS:
    case SDRAM_R1BAS:
    case SDRAM_R2BAS:
    case SDRAM_R3BAS:
        if (s->bank[dcrn - SDRAM_R0BAS].size) {
            ret = sdram_ddr2_bcr(s->bank[dcrn - SDRAM_R0BAS].base,
                                 s->bank[dcrn - SDRAM_R0BAS].size);
        }
        break;
    case SDRAM_CONF1HB:
    case SDRAM_CONF1LL:
    case SDRAM_CONFPATHB:
    case SDRAM_PLBADDULL:
    case SDRAM_PLBADDUHB:
        break;
    case SDRAM0_CFGADDR:
        ret = s->addr;
        break;
    case SDRAM0_CFGDATA:
        switch (s->addr) {
        case 0x14: /* SDRAM_MCSTAT (405EX) */
        case 0x1F:
            ret = 0x80000000;
            break;
        case 0x21: /* SDRAM_MCOPT2 */
            ret = s->mcopt2;
            break;
        case 0x40: /* SDRAM_MB0CF */
            ret = 0x00008001;
            break;
        case 0x7A: /* SDRAM_DLCR */
            ret = 0x02000000;
            break;
        case 0xE1: /* SDR0_DDR0 */
            ret = SDR0_DDR0_DDRM_ENCODE(1) | SDR0_DDR0_DDRM_DDR1;
            break;
        default:
            break;
        }
        break;
    default:
        break;
    }

    return ret;
}

#define SDRAM_DDR2_MCOPT2_DCEN BIT(27)

static void sdram_ddr2_dcr_write(void *opaque, int dcrn, uint32_t val)
{
    Ppc4xxSdramDdr2State *s = opaque;
    int i;

    switch (dcrn) {
    case SDRAM_R0BAS:
    case SDRAM_R1BAS:
    case SDRAM_R2BAS:
    case SDRAM_R3BAS:
    case SDRAM_CONF1HB:
    case SDRAM_CONF1LL:
    case SDRAM_CONFPATHB:
    case SDRAM_PLBADDULL:
    case SDRAM_PLBADDUHB:
        break;
    case SDRAM0_CFGADDR:
        s->addr = val;
        break;
    case SDRAM0_CFGDATA:
        switch (s->addr) {
        case 0x00: /* B0CR */
            break;
        case 0x21: /* SDRAM_MCOPT2 */
            if (!(s->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) &&
                (val & SDRAM_DDR2_MCOPT2_DCEN)) {
                trace_ppc4xx_sdram_enable("enable");
                /* validate all RAM mappings */
                for (i = 0; i < s->nbanks; i++) {
                    if (s->bank[i].size) {
                        sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr,
                                           s->bank[i].base, s->bank[i].size,
                                           1);
                    }
                }
                s->mcopt2 |= SDRAM_DDR2_MCOPT2_DCEN;
            } else if ((s->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) &&
                       !(val & SDRAM_DDR2_MCOPT2_DCEN)) {
                trace_ppc4xx_sdram_enable("disable");
                /* invalidate all RAM mappings */
                for (i = 0; i < s->nbanks; i++) {
                    if (s->bank[i].size) {
                        sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr,
                                           s->bank[i].base, s->bank[i].size,
                                           0);
                    }
                }
                s->mcopt2 &= ~SDRAM_DDR2_MCOPT2_DCEN;
            }
            break;
        default:
            break;
        }
        break;
    default:
        break;
    }
}

static void ppc4xx_sdram_ddr2_reset(DeviceState *dev)
{
    Ppc4xxSdramDdr2State *s = PPC4xx_SDRAM_DDR2(dev);

    s->addr = 0;
    s->mcopt2 = 0;
}

static void ppc4xx_sdram_ddr2_realize(DeviceState *dev, Error **errp)
{
    Ppc4xxSdramDdr2State *s = PPC4xx_SDRAM_DDR2(dev);
    Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev);
    /*
     * SoC also has 4 GiB but that causes problem with 32 bit
     * builds (4*GiB overflows the 32 bit ram_addr_t).
     */
    const ram_addr_t valid_bank_sizes[] = {
        2 * GiB, 1 * GiB, 512 * MiB, 256 * MiB, 128 * MiB,
        64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 0
    };
    int i;

    if (s->nbanks < 1 || s->nbanks > 4) {
        error_setg(errp, "Invalid number of RAM banks");
        return;
    }
    if (!s->dram_mr) {
        error_setg(errp, "Missing dram memory region");
        return;
    }
    if (!ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank,
                            valid_bank_sizes, errp)) {
        return;
    }
    for (i = 0; i < s->nbanks; i++) {
        if (s->bank[i].size) {
            s->bank[i].bcr = sdram_ddr2_bcr(s->bank[i].base, s->bank[i].size);
            s->bank[i].bcr &= SDRAM_DDR2_BCR_MASK;
            sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr,
                               s->bank[i].base, s->bank[i].size, 0);
        } else {
            sdram_bank_set_bcr(&s->bank[i], 0, 0, 0, 0);
        }
        trace_ppc4xx_sdram_init(sdram_ddr2_base(s->bank[i].bcr),
                                sdram_ddr2_size(s->bank[i].bcr),
                                s->bank[i].bcr);
    }

    ppc4xx_dcr_register(dcr, SDRAM0_CFGADDR,
                        s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
    ppc4xx_dcr_register(dcr, SDRAM0_CFGDATA,
                        s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);

    ppc4xx_dcr_register(dcr, SDRAM_R0BAS,
                        s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
    ppc4xx_dcr_register(dcr, SDRAM_R1BAS,
                        s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
    ppc4xx_dcr_register(dcr, SDRAM_R2BAS,
                        s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
    ppc4xx_dcr_register(dcr, SDRAM_R3BAS,
                        s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
    ppc4xx_dcr_register(dcr, SDRAM_CONF1HB,
                        s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
    ppc4xx_dcr_register(dcr, SDRAM_PLBADDULL,
                        s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
    ppc4xx_dcr_register(dcr, SDRAM_CONF1LL,
                        s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
    ppc4xx_dcr_register(dcr, SDRAM_CONFPATHB,
                        s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
    ppc4xx_dcr_register(dcr, SDRAM_PLBADDUHB,
                        s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
}

static Property ppc4xx_sdram_ddr2_props[] = {
    DEFINE_PROP_LINK("dram", Ppc4xxSdramDdr2State, dram_mr, TYPE_MEMORY_REGION,
                     MemoryRegion *),
    DEFINE_PROP_UINT32("nbanks", Ppc4xxSdramDdr2State, nbanks, 4),
    DEFINE_PROP_END_OF_LIST(),
};

static void ppc4xx_sdram_ddr2_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);

    dc->realize = ppc4xx_sdram_ddr2_realize;
    dc->reset = ppc4xx_sdram_ddr2_reset;
    /* Reason: only works as function of a ppc4xx SoC */
    dc->user_creatable = false;
    device_class_set_props(dc, ppc4xx_sdram_ddr2_props);
}

void ppc4xx_sdram_ddr2_enable(Ppc4xxSdramDdr2State *s)
{
    sdram_ddr2_dcr_write(s, SDRAM0_CFGADDR, 0x21);
    sdram_ddr2_dcr_write(s, SDRAM0_CFGDATA, 0x08000000);
}

static const TypeInfo ppc4xx_sdram_types[] = {
    {
        .name           = TYPE_PPC4xx_SDRAM_DDR,
        .parent         = TYPE_PPC4xx_DCR_DEVICE,
        .instance_size  = sizeof(Ppc4xxSdramDdrState),
        .class_init     = ppc4xx_sdram_ddr_class_init,
    }, {
        .name           = TYPE_PPC4xx_SDRAM_DDR2,
        .parent         = TYPE_PPC4xx_DCR_DEVICE,
        .instance_size  = sizeof(Ppc4xxSdramDdr2State),
        .class_init     = ppc4xx_sdram_ddr2_class_init,
    }
};

DEFINE_TYPES(ppc4xx_sdram_types)
