/*
 * 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)
{
    hwaddr size;
    int sh;

    sh = (bcr >> 17) & 0x7;
    if (sh == 7) {
        size = -1;
    } else {
        size = (4 * MiB) << sh;
    }

    return size;
}

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 " TARGET_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)
{
    hwaddr size;
    int sh;

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

    return size;
}

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)
