diff mbox

[PATCHv3,11/14] unicore32-softmmu: Add puv3 pm support

Message ID 7e50d5a67915d77eecf86ae77ceb2ac5091cc661.1340010818.git.gxt@mprc.pku.edu.cn
State New
Headers show

Commit Message

Guan Xuetao June 18, 2012, 9:25 a.m. UTC
This patch adds puv3 pm (power management) support,
include pm device simulation for kernel booting.

Signed-off-by: Guan Xuetao <gxt@mprc.pku.edu.cn>
---
 hw/Makefile.objs |    1 +
 hw/puv3.c        |    1 +
 hw/puv3_pm.c     |  148 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 150 insertions(+), 0 deletions(-)
 create mode 100644 hw/puv3_pm.c

Comments

Blue Swirl June 18, 2012, 8:05 p.m. UTC | #1
On Mon, Jun 18, 2012 at 9:25 AM, Guan Xuetao <gxt@mprc.pku.edu.cn> wrote:
> This patch adds puv3 pm (power management) support,
> include pm device simulation for kernel booting.
>
> Signed-off-by: Guan Xuetao <gxt@mprc.pku.edu.cn>
> ---
>  hw/Makefile.objs |    1 +
>  hw/puv3.c        |    1 +
>  hw/puv3_pm.c     |  148 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 150 insertions(+), 0 deletions(-)
>  create mode 100644 hw/puv3_pm.c
>
> diff --git a/hw/Makefile.objs b/hw/Makefile.objs
> index a9709f5..4641373 100644
> --- a/hw/Makefile.objs
> +++ b/hw/Makefile.objs
> @@ -70,6 +70,7 @@ hw-obj-$(CONFIG_XILINX_AXI) += xilinx_axienet.o
>  hw-obj-$(CONFIG_PUV3) += puv3_intc.o
>  hw-obj-$(CONFIG_PUV3) += puv3_ost.o
>  hw-obj-$(CONFIG_PUV3) += puv3_gpio.o
> +hw-obj-$(CONFIG_PUV3) += puv3_pm.o
>
>  # PCI watchdog devices
>  hw-obj-$(CONFIG_PCI) += wdt_i6300esb.o
> diff --git a/hw/puv3.c b/hw/puv3.c
> index 80aaa27..c86613d 100644
> --- a/hw/puv3.c
> +++ b/hw/puv3.c
> @@ -48,6 +48,7 @@ static void puv3_soc_init(CPUUniCore32State *env)
>     }
>
>     /* Initialize minimal necessary devices for kernel booting */
> +    sysbus_create_simple("puv3_pm", PUV3_PM_BASE, NULL);
>     sysbus_create_simple("puv3_ost", PUV3_OST_BASE, irqs[PUV3_IRQS_OST0]);
>     sysbus_create_varargs("puv3_gpio", PUV3_GPIO_BASE,
>             irqs[PUV3_IRQS_GPIOLOW0], irqs[PUV3_IRQS_GPIOLOW1],
> diff --git a/hw/puv3_pm.c b/hw/puv3_pm.c
> new file mode 100644
> index 0000000..4b914ed
> --- /dev/null
> +++ b/hw/puv3_pm.c
> @@ -0,0 +1,148 @@
> +/*
> + * Power Management device simulation in PKUnity SoC
> + *
> + * Copyright (C) 2010-2012 Guan Xuetao
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation, or any later version.
> + * See the COPYING file in the top-level directory.
> + */
> +#include "hw.h"
> +#include "sysbus.h"
> +
> +#undef DEBUG_PUV3
> +#include "puv3.h"
> +
> +typedef struct {
> +    SysBusDevice busdev;
> +    MemoryRegion iomem;
> +
> +    uint32_t reg_PMCR;
> +    uint32_t reg_PCGR;
> +    uint32_t reg_PLL_SYS_CFG;
> +    uint32_t reg_PLL_DDR_CFG;
> +    uint32_t reg_PLL_VGA_CFG;
> +    uint32_t reg_DIVCFG;
> +} PUV3PMState;
> +
> +static uint64_t puv3_pm_read(void *opaque, target_phys_addr_t offset,
> +        unsigned size)
> +{
> +    PUV3PMState *s = (PUV3PMState *) opaque;
> +    uint32_t ret;
> +
> +    switch (offset) {
> +    case 0x14:
> +        ret = s->reg_PCGR;
> +        break;
> +    case 0x18:
> +        ret = s->reg_PLL_SYS_CFG;
> +        break;
> +    case 0x1c:
> +        ret = s->reg_PLL_DDR_CFG;
> +        break;
> +    case 0x20:
> +        ret = s->reg_PLL_VGA_CFG;
> +        break;
> +    case 0x24:
> +        ret = s->reg_DIVCFG;
> +        break;
> +    case 0x28: /* PLL SYS STATUS */
> +        ret = 0x00002401;
> +        break;
> +    case 0x2c: /* PLL DDR STATUS */
> +        ret = 0x00100c00;
> +        break;
> +    case 0x30: /* PLL VGA STATUS */
> +        ret = 0x00003801;
> +        break;
> +    case 0x34: /* DIV STATUS */
> +        ret = 0x22f52015;
> +        break;
> +    case 0x38: /* SW RESET */
> +        ret = 0x0;
> +        break;
> +    case 0x44: /* PLL DFC DONE */
> +        ret = 0x7;
> +        break;
> +    default:
> +        hw_error("%s: Bad offset 0x%x\n", __func__, offset);
> +    }
> +    DPRINTF("offset 0x%x, value 0x%x\n", offset, ret);
> +
> +    return ret;
> +}
> +
> +static void puv3_pm_write(void *opaque, target_phys_addr_t offset,
> +        uint64_t value, unsigned size)
> +{
> +    PUV3PMState *s = (PUV3PMState *) opaque;
> +
> +    switch (offset) {
> +    case 0x0:
> +        s->reg_PMCR = value;

Missing 'break' or a comment about fall through.

> +    case 0x14:
> +        s->reg_PCGR = value;
> +        break;
> +    case 0x18:
> +        s->reg_PLL_SYS_CFG = value;
> +        break;
> +    case 0x1c:
> +        s->reg_PLL_DDR_CFG = value;
> +        break;
> +    case 0x20:
> +        s->reg_PLL_VGA_CFG = value;
> +        break;
> +    case 0x24:
> +    case 0x38:
> +        break;
> +    default:
> +        hw_error("%s: Bad offset 0x%x\n", __func__, offset);
> +    }
> +    DPRINTF("offset 0x%x, value 0x%x\n", offset, value);
> +}
> +
> +static const MemoryRegionOps puv3_pm_ops = {
> +    .read = puv3_pm_read,
> +    .write = puv3_pm_write,
> +    .impl = {
> +        .min_access_size = 4,
> +        .max_access_size = 4,
> +    },
> +    .endianness = DEVICE_NATIVE_ENDIAN,
> +};
> +
> +static int puv3_pm_init(SysBusDevice *dev)
> +{
> +    PUV3PMState *s = FROM_SYSBUS(PUV3PMState, dev);
> +
> +    s->reg_PCGR = 0x0;
> +
> +    memory_region_init_io(&s->iomem, &puv3_pm_ops, s, "puv3_pm",
> +            PUV3_REGS_OFFSET);
> +    sysbus_init_mmio(dev, &s->iomem);
> +
> +    return 0;
> +}
> +
> +static void puv3_pm_class_init(ObjectClass *klass, void *data)
> +{
> +    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
> +
> +    sdc->init = puv3_pm_init;
> +}
> +
> +static const TypeInfo puv3_pm_info = {
> +    .name = "puv3_pm",
> +    .parent = TYPE_SYS_BUS_DEVICE,
> +    .instance_size = sizeof(PUV3PMState),
> +    .class_init = puv3_pm_class_init,
> +};
> +
> +static void puv3_pm_register_type(void)
> +{
> +    type_register_static(&puv3_pm_info);
> +}
> +
> +type_init(puv3_pm_register_type)
> --
> 1.7.0.4
>
Guan Xuetao June 20, 2012, 2 a.m. UTC | #2
On Mon, 2012-06-18 at 20:05 +0000, Blue Swirl wrote:
[snip]
> > +static void puv3_pm_write(void *opaque, target_phys_addr_t offset,
> > +        uint64_t value, unsigned size)
> > +{
> > +    PUV3PMState *s = (PUV3PMState *) opaque;
> > +
> > +    switch (offset) {
> > +    case 0x0:
> > +        s->reg_PMCR = value;
> 
> Missing 'break' or a comment about fall through.
Yes, 'break' is missed here.
Thanks ever so much.

Guan Xuetao
diff mbox

Patch

diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index a9709f5..4641373 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -70,6 +70,7 @@  hw-obj-$(CONFIG_XILINX_AXI) += xilinx_axienet.o
 hw-obj-$(CONFIG_PUV3) += puv3_intc.o
 hw-obj-$(CONFIG_PUV3) += puv3_ost.o
 hw-obj-$(CONFIG_PUV3) += puv3_gpio.o
+hw-obj-$(CONFIG_PUV3) += puv3_pm.o
 
 # PCI watchdog devices
 hw-obj-$(CONFIG_PCI) += wdt_i6300esb.o
diff --git a/hw/puv3.c b/hw/puv3.c
index 80aaa27..c86613d 100644
--- a/hw/puv3.c
+++ b/hw/puv3.c
@@ -48,6 +48,7 @@  static void puv3_soc_init(CPUUniCore32State *env)
     }
 
     /* Initialize minimal necessary devices for kernel booting */
+    sysbus_create_simple("puv3_pm", PUV3_PM_BASE, NULL);
     sysbus_create_simple("puv3_ost", PUV3_OST_BASE, irqs[PUV3_IRQS_OST0]);
     sysbus_create_varargs("puv3_gpio", PUV3_GPIO_BASE,
             irqs[PUV3_IRQS_GPIOLOW0], irqs[PUV3_IRQS_GPIOLOW1],
diff --git a/hw/puv3_pm.c b/hw/puv3_pm.c
new file mode 100644
index 0000000..4b914ed
--- /dev/null
+++ b/hw/puv3_pm.c
@@ -0,0 +1,148 @@ 
+/*
+ * Power Management device simulation in PKUnity SoC
+ *
+ * Copyright (C) 2010-2012 Guan Xuetao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation, or any later version.
+ * See the COPYING file in the top-level directory.
+ */
+#include "hw.h"
+#include "sysbus.h"
+
+#undef DEBUG_PUV3
+#include "puv3.h"
+
+typedef struct {
+    SysBusDevice busdev;
+    MemoryRegion iomem;
+
+    uint32_t reg_PMCR;
+    uint32_t reg_PCGR;
+    uint32_t reg_PLL_SYS_CFG;
+    uint32_t reg_PLL_DDR_CFG;
+    uint32_t reg_PLL_VGA_CFG;
+    uint32_t reg_DIVCFG;
+} PUV3PMState;
+
+static uint64_t puv3_pm_read(void *opaque, target_phys_addr_t offset,
+        unsigned size)
+{
+    PUV3PMState *s = (PUV3PMState *) opaque;
+    uint32_t ret;
+
+    switch (offset) {
+    case 0x14:
+        ret = s->reg_PCGR;
+        break;
+    case 0x18:
+        ret = s->reg_PLL_SYS_CFG;
+        break;
+    case 0x1c:
+        ret = s->reg_PLL_DDR_CFG;
+        break;
+    case 0x20:
+        ret = s->reg_PLL_VGA_CFG;
+        break;
+    case 0x24:
+        ret = s->reg_DIVCFG;
+        break;
+    case 0x28: /* PLL SYS STATUS */
+        ret = 0x00002401;
+        break;
+    case 0x2c: /* PLL DDR STATUS */
+        ret = 0x00100c00;
+        break;
+    case 0x30: /* PLL VGA STATUS */
+        ret = 0x00003801;
+        break;
+    case 0x34: /* DIV STATUS */
+        ret = 0x22f52015;
+        break;
+    case 0x38: /* SW RESET */
+        ret = 0x0;
+        break;
+    case 0x44: /* PLL DFC DONE */
+        ret = 0x7;
+        break;
+    default:
+        hw_error("%s: Bad offset 0x%x\n", __func__, offset);
+    }
+    DPRINTF("offset 0x%x, value 0x%x\n", offset, ret);
+
+    return ret;
+}
+
+static void puv3_pm_write(void *opaque, target_phys_addr_t offset,
+        uint64_t value, unsigned size)
+{
+    PUV3PMState *s = (PUV3PMState *) opaque;
+
+    switch (offset) {
+    case 0x0:
+        s->reg_PMCR = value;
+    case 0x14:
+        s->reg_PCGR = value;
+        break;
+    case 0x18:
+        s->reg_PLL_SYS_CFG = value;
+        break;
+    case 0x1c:
+        s->reg_PLL_DDR_CFG = value;
+        break;
+    case 0x20:
+        s->reg_PLL_VGA_CFG = value;
+        break;
+    case 0x24:
+    case 0x38:
+        break;
+    default:
+        hw_error("%s: Bad offset 0x%x\n", __func__, offset);
+    }
+    DPRINTF("offset 0x%x, value 0x%x\n", offset, value);
+}
+
+static const MemoryRegionOps puv3_pm_ops = {
+    .read = puv3_pm_read,
+    .write = puv3_pm_write,
+    .impl = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static int puv3_pm_init(SysBusDevice *dev)
+{
+    PUV3PMState *s = FROM_SYSBUS(PUV3PMState, dev);
+
+    s->reg_PCGR = 0x0;
+
+    memory_region_init_io(&s->iomem, &puv3_pm_ops, s, "puv3_pm",
+            PUV3_REGS_OFFSET);
+    sysbus_init_mmio(dev, &s->iomem);
+
+    return 0;
+}
+
+static void puv3_pm_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = puv3_pm_init;
+}
+
+static const TypeInfo puv3_pm_info = {
+    .name = "puv3_pm",
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(PUV3PMState),
+    .class_init = puv3_pm_class_init,
+};
+
+static void puv3_pm_register_type(void)
+{
+    type_register_static(&puv3_pm_info);
+}
+
+type_init(puv3_pm_register_type)