These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / hw / misc / puv3_pm.c
1 /*
2  * Power Management device simulation in PKUnity SoC
3  *
4  * Copyright (C) 2010-2012 Guan Xuetao
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation, or any later version.
9  * See the COPYING file in the top-level directory.
10  */
11 #include "qemu/osdep.h"
12 #include "hw/hw.h"
13 #include "hw/sysbus.h"
14
15 #undef DEBUG_PUV3
16 #include "hw/unicore32/puv3.h"
17
18 #define TYPE_PUV3_PM "puv3_pm"
19 #define PUV3_PM(obj) OBJECT_CHECK(PUV3PMState, (obj), TYPE_PUV3_PM)
20
21 typedef struct PUV3PMState {
22     SysBusDevice parent_obj;
23
24     MemoryRegion iomem;
25
26     uint32_t reg_PMCR;
27     uint32_t reg_PCGR;
28     uint32_t reg_PLL_SYS_CFG;
29     uint32_t reg_PLL_DDR_CFG;
30     uint32_t reg_PLL_VGA_CFG;
31     uint32_t reg_DIVCFG;
32 } PUV3PMState;
33
34 static uint64_t puv3_pm_read(void *opaque, hwaddr offset,
35         unsigned size)
36 {
37     PUV3PMState *s = opaque;
38     uint32_t ret = 0;
39
40     switch (offset) {
41     case 0x14:
42         ret = s->reg_PCGR;
43         break;
44     case 0x18:
45         ret = s->reg_PLL_SYS_CFG;
46         break;
47     case 0x1c:
48         ret = s->reg_PLL_DDR_CFG;
49         break;
50     case 0x20:
51         ret = s->reg_PLL_VGA_CFG;
52         break;
53     case 0x24:
54         ret = s->reg_DIVCFG;
55         break;
56     case 0x28: /* PLL SYS STATUS */
57         ret = 0x00002401;
58         break;
59     case 0x2c: /* PLL DDR STATUS */
60         ret = 0x00100c00;
61         break;
62     case 0x30: /* PLL VGA STATUS */
63         ret = 0x00003801;
64         break;
65     case 0x34: /* DIV STATUS */
66         ret = 0x22f52015;
67         break;
68     case 0x38: /* SW RESET */
69         ret = 0x0;
70         break;
71     case 0x44: /* PLL DFC DONE */
72         ret = 0x7;
73         break;
74     default:
75         DPRINTF("Bad offset 0x%x\n", offset);
76     }
77     DPRINTF("offset 0x%x, value 0x%x\n", offset, ret);
78
79     return ret;
80 }
81
82 static void puv3_pm_write(void *opaque, hwaddr offset,
83         uint64_t value, unsigned size)
84 {
85     PUV3PMState *s = opaque;
86
87     switch (offset) {
88     case 0x0:
89         s->reg_PMCR = value;
90         break;
91     case 0x14:
92         s->reg_PCGR = value;
93         break;
94     case 0x18:
95         s->reg_PLL_SYS_CFG = value;
96         break;
97     case 0x1c:
98         s->reg_PLL_DDR_CFG = value;
99         break;
100     case 0x20:
101         s->reg_PLL_VGA_CFG = value;
102         break;
103     case 0x24:
104     case 0x38:
105         break;
106     default:
107         DPRINTF("Bad offset 0x%x\n", offset);
108     }
109     DPRINTF("offset 0x%x, value 0x%x\n", offset, value);
110 }
111
112 static const MemoryRegionOps puv3_pm_ops = {
113     .read = puv3_pm_read,
114     .write = puv3_pm_write,
115     .impl = {
116         .min_access_size = 4,
117         .max_access_size = 4,
118     },
119     .endianness = DEVICE_NATIVE_ENDIAN,
120 };
121
122 static int puv3_pm_init(SysBusDevice *dev)
123 {
124     PUV3PMState *s = PUV3_PM(dev);
125
126     s->reg_PCGR = 0x0;
127
128     memory_region_init_io(&s->iomem, OBJECT(s), &puv3_pm_ops, s, "puv3_pm",
129             PUV3_REGS_OFFSET);
130     sysbus_init_mmio(dev, &s->iomem);
131
132     return 0;
133 }
134
135 static void puv3_pm_class_init(ObjectClass *klass, void *data)
136 {
137     SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
138
139     sdc->init = puv3_pm_init;
140 }
141
142 static const TypeInfo puv3_pm_info = {
143     .name = TYPE_PUV3_PM,
144     .parent = TYPE_SYS_BUS_DEVICE,
145     .instance_size = sizeof(PUV3PMState),
146     .class_init = puv3_pm_class_init,
147 };
148
149 static void puv3_pm_register_type(void)
150 {
151     type_register_static(&puv3_pm_info);
152 }
153
154 type_init(puv3_pm_register_type)