summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--hw/ppc/ppc440.h2
-rw-r--r--hw/ppc/ppc440_uc.c121
-rw-r--r--hw/ppc/sam460ex.c9
-rw-r--r--include/hw/ppc/ppc4xx.h18
4 files changed, 97 insertions, 53 deletions
diff --git a/hw/ppc/ppc440.h b/hw/ppc/ppc440.h
index 29f6f14ed7..7c24db8504 100644
--- a/hw/ppc/ppc440.h
+++ b/hw/ppc/ppc440.h
@@ -16,8 +16,6 @@
void ppc4xx_l2sram_init(CPUPPCState *env);
void ppc4xx_cpr_init(CPUPPCState *env);
void ppc4xx_sdr_init(CPUPPCState *env);
-void ppc440_sdram_init(CPUPPCState *env, int nbanks,
- MemoryRegion *ram);
void ppc4xx_ahb_init(CPUPPCState *env);
void ppc4xx_dma_init(CPUPPCState *env, int dcr_base);
void ppc460ex_pcie_init(CPUPPCState *env);
diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index dd873d892c..55082f2b88 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -484,13 +484,6 @@ void ppc4xx_sdr_init(CPUPPCState *env)
/*****************************************************************************/
/* SDRAM controller */
-typedef struct ppc440_sdram_t {
- uint32_t addr;
- uint32_t mcopt2;
- int nbanks; /* Banks to use from the 4, e.g. when board has less slots */
- Ppc4xxSdramBank bank[4];
-} ppc440_sdram_t;
-
enum {
SDRAM0_CFGADDR = 0x10,
SDRAM0_CFGDATA,
@@ -581,7 +574,7 @@ static void sdram_bank_unmap(Ppc4xxSdramBank *bank)
object_unparent(OBJECT(&bank->container));
}
-static void sdram_ddr2_set_bcr(ppc440_sdram_t *sdram, int i,
+static void sdram_ddr2_set_bcr(Ppc4xxSdramDdr2State *sdram, int i,
uint32_t bcr, int enabled)
{
if (sdram->bank[i].bcr & 1) {
@@ -597,7 +590,7 @@ static void sdram_ddr2_set_bcr(ppc440_sdram_t *sdram, int i,
}
}
-static void sdram_ddr2_map_bcr(ppc440_sdram_t *sdram)
+static void sdram_ddr2_map_bcr(Ppc4xxSdramDdr2State *sdram)
{
int i;
@@ -612,7 +605,7 @@ static void sdram_ddr2_map_bcr(ppc440_sdram_t *sdram)
}
}
-static void sdram_ddr2_unmap_bcr(ppc440_sdram_t *sdram)
+static void sdram_ddr2_unmap_bcr(Ppc4xxSdramDdr2State *sdram)
{
int i;
@@ -625,7 +618,7 @@ static void sdram_ddr2_unmap_bcr(ppc440_sdram_t *sdram)
static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn)
{
- ppc440_sdram_t *sdram = opaque;
+ Ppc4xxSdramDdr2State *sdram = opaque;
uint32_t ret = 0;
switch (dcrn) {
@@ -680,7 +673,7 @@ static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn)
static void sdram_ddr2_dcr_write(void *opaque, int dcrn, uint32_t val)
{
- ppc440_sdram_t *sdram = opaque;
+ Ppc4xxSdramDdr2State *sdram = opaque;
switch (dcrn) {
case SDRAM_R0BAS:
@@ -724,18 +717,18 @@ static void sdram_ddr2_dcr_write(void *opaque, int dcrn, uint32_t val)
}
}
-static void sdram_ddr2_reset(void *opaque)
+static void ppc4xx_sdram_ddr2_reset(DeviceState *dev)
{
- ppc440_sdram_t *sdram = opaque;
+ Ppc4xxSdramDdr2State *sdram = PPC4xx_SDRAM_DDR2(dev);
sdram->addr = 0;
sdram->mcopt2 = 0;
}
-void ppc440_sdram_init(CPUPPCState *env, int nbanks,
- MemoryRegion *ram)
+static void ppc4xx_sdram_ddr2_realize(DeviceState *dev, Error **errp)
{
- ppc440_sdram_t *s;
+ 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).
@@ -745,41 +738,75 @@ void ppc440_sdram_init(CPUPPCState *env, int nbanks,
64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 0
};
- s = g_malloc0(sizeof(*s));
- s->nbanks = nbanks;
- ppc4xx_sdram_banks(ram, s->nbanks, s->bank, valid_bank_sizes);
- qemu_register_reset(&sdram_ddr2_reset, s);
- ppc_dcr_register(env, SDRAM0_CFGADDR,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
- ppc_dcr_register(env, SDRAM0_CFGDATA,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
-
- ppc_dcr_register(env, SDRAM_R0BAS,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
- ppc_dcr_register(env, SDRAM_R1BAS,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
- ppc_dcr_register(env, SDRAM_R2BAS,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
- ppc_dcr_register(env, SDRAM_R3BAS,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
- ppc_dcr_register(env, SDRAM_CONF1HB,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
- ppc_dcr_register(env, SDRAM_PLBADDULL,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
- ppc_dcr_register(env, SDRAM_CONF1LL,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
- ppc_dcr_register(env, SDRAM_CONFPATHB,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
- ppc_dcr_register(env, SDRAM_PLBADDUHB,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
+ 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;
+ }
+ ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank, valid_bank_sizes);
+
+ 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(CPUPPCState *env)
+void ppc4xx_sdram_ddr2_enable(Ppc4xxSdramDdr2State *s)
{
- ppc_dcr_write(env->dcr_env, SDRAM0_CFGADDR, 0x21);
- ppc_dcr_write(env->dcr_env, SDRAM0_CFGDATA, 0x08000000);
+ sdram_ddr2_dcr_write(s, SDRAM0_CFGADDR, 0x21);
+ sdram_ddr2_dcr_write(s, SDRAM0_CFGDATA, 0x08000000);
}
+static const TypeInfo ppc4xx_types[] = {
+ {
+ .name = TYPE_PPC4xx_SDRAM_DDR2,
+ .parent = TYPE_PPC4xx_DCR_DEVICE,
+ .instance_size = sizeof(Ppc4xxSdramDdr2State),
+ .class_init = ppc4xx_sdram_ddr2_class_init,
+ }
+};
+DEFINE_TYPES(ppc4xx_types)
+
/*****************************************************************************/
/* PLB to AHB bridge */
enum {
diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c
index 13055a8916..f03cdc9ecc 100644
--- a/hw/ppc/sam460ex.c
+++ b/hw/ppc/sam460ex.c
@@ -342,14 +342,19 @@ static void sam460ex_init(MachineState *machine)
error_report("Memory below 64 MiB is not supported");
exit(1);
}
+ dev = qdev_new(TYPE_PPC4xx_SDRAM_DDR2);
+ object_property_set_link(OBJECT(dev), "dram", OBJECT(machine->ram),
+ &error_abort);
/*
* Put all RAM on first bank because board has one slot
* and firmware only checks that
*/
- ppc440_sdram_init(env, 1, machine->ram);
+ object_property_set_int(OBJECT(dev), "nbanks", 1, &error_abort);
+ ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(dev), cpu, &error_fatal);
+ object_unref(OBJECT(dev));
/* FIXME: does 460EX have ECC interrupts? */
/* Enable SDRAM memory regions as we may boot without firmware */
- ppc4xx_sdram_ddr2_enable(env);
+ ppc4xx_sdram_ddr2_enable(PPC4xx_SDRAM_DDR2(dev));
/* IIC controllers and devices */
dev = sysbus_create_simple(TYPE_PPC4xx_I2C, 0x4ef600700,
diff --git a/include/hw/ppc/ppc4xx.h b/include/hw/ppc/ppc4xx.h
index fd0b3ca82a..ff88385ac0 100644
--- a/include/hw/ppc/ppc4xx.h
+++ b/include/hw/ppc/ppc4xx.h
@@ -37,8 +37,6 @@ typedef struct {
uint32_t bcr;
} Ppc4xxSdramBank;
-void ppc4xx_sdram_ddr2_enable(CPUPPCState *env);
-
void ppc4xx_sdram_banks(MemoryRegion *ram, int nr_banks,
Ppc4xxSdramBank ram_banks[],
const ram_addr_t sdram_bank_sizes[]);
@@ -138,4 +136,20 @@ struct Ppc4xxSdramDdrState {
void ppc4xx_sdram_ddr_enable(Ppc4xxSdramDdrState *s);
+/* SDRAM DDR2 controller */
+#define TYPE_PPC4xx_SDRAM_DDR2 "ppc4xx-sdram-ddr2"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc4xxSdramDdr2State, PPC4xx_SDRAM_DDR2);
+struct Ppc4xxSdramDdr2State {
+ Ppc4xxDcrDeviceState parent_obj;
+
+ MemoryRegion *dram_mr;
+ uint32_t nbanks; /* Banks to use from 4, e.g. when board has less slots */
+ Ppc4xxSdramBank bank[4];
+
+ uint32_t addr;
+ uint32_t mcopt2;
+};
+
+void ppc4xx_sdram_ddr2_enable(Ppc4xxSdramDdr2State *s);
+
#endif /* PPC4XX_H */