23
#include "qemu/osdep.h"
24
#include "qemu/units.h"
26
#include "migration/vmstate.h"
28
#include "qemu/module.h"
29
#include "hw/misc/allwinner-a10-ccm.h"
33
REG_PLL1_CFG = 0x0000,
34
REG_PLL1_TUN = 0x0004,
35
REG_PLL2_CFG = 0x0008,
36
REG_PLL2_TUN = 0x000C,
37
REG_PLL3_CFG = 0x0010,
38
REG_PLL4_CFG = 0x0018,
39
REG_PLL5_CFG = 0x0020,
40
REG_PLL5_TUN = 0x0024,
41
REG_PLL6_CFG = 0x0028,
42
REG_PLL6_TUN = 0x002C,
43
REG_PLL7_CFG = 0x0030,
44
REG_PLL1_TUN2 = 0x0038,
45
REG_PLL5_TUN2 = 0x003C,
46
REG_PLL8_CFG = 0x0040,
47
REG_OSC24M_CFG = 0x0050,
48
REG_CPU_AHB_APB0_CFG = 0x0054,
51
#define REG_INDEX(offset) (offset / sizeof(uint32_t))
55
REG_PLL1_CFG_RST = 0x21005000,
56
REG_PLL1_TUN_RST = 0x0A101000,
57
REG_PLL2_CFG_RST = 0x08100010,
58
REG_PLL2_TUN_RST = 0x00000000,
59
REG_PLL3_CFG_RST = 0x0010D063,
60
REG_PLL4_CFG_RST = 0x21009911,
61
REG_PLL5_CFG_RST = 0x11049280,
62
REG_PLL5_TUN_RST = 0x14888000,
63
REG_PLL6_CFG_RST = 0x21009911,
64
REG_PLL6_TUN_RST = 0x00000000,
65
REG_PLL7_CFG_RST = 0x0010D063,
66
REG_PLL1_TUN2_RST = 0x00000000,
67
REG_PLL5_TUN2_RST = 0x00000000,
68
REG_PLL8_CFG_RST = 0x21009911,
69
REG_OSC24M_CFG_RST = 0x00138013,
70
REG_CPU_AHB_APB0_CFG_RST = 0x00010010,
73
static uint64_t allwinner_a10_ccm_read(void *opaque, hwaddr offset,
76
const AwA10ClockCtlState *s = AW_A10_CCM(opaque);
77
const uint32_t idx = REG_INDEX(offset);
95
case REG_CPU_AHB_APB0_CFG:
97
case 0x158 ... AW_A10_CCM_IOSIZE:
98
qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n",
99
__func__, (uint32_t)offset);
102
qemu_log_mask(LOG_UNIMP, "%s: unimplemented read offset 0x%04x\n",
103
__func__, (uint32_t)offset);
110
static void allwinner_a10_ccm_write(void *opaque, hwaddr offset,
111
uint64_t val, unsigned size)
113
AwA10ClockCtlState *s = AW_A10_CCM(opaque);
114
const uint32_t idx = REG_INDEX(offset);
132
case REG_CPU_AHB_APB0_CFG:
134
case 0x158 ... AW_A10_CCM_IOSIZE:
135
qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n",
136
__func__, (uint32_t)offset);
139
qemu_log_mask(LOG_UNIMP, "%s: unimplemented write offset 0x%04x\n",
140
__func__, (uint32_t)offset);
144
s->regs[idx] = (uint32_t) val;
147
static const MemoryRegionOps allwinner_a10_ccm_ops = {
148
.read = allwinner_a10_ccm_read,
149
.write = allwinner_a10_ccm_write,
150
.endianness = DEVICE_NATIVE_ENDIAN,
152
.min_access_size = 4,
153
.max_access_size = 4,
155
.impl.min_access_size = 4,
158
static void allwinner_a10_ccm_reset_enter(Object *obj, ResetType type)
160
AwA10ClockCtlState *s = AW_A10_CCM(obj);
163
s->regs[REG_INDEX(REG_PLL1_CFG)] = REG_PLL1_CFG_RST;
164
s->regs[REG_INDEX(REG_PLL1_TUN)] = REG_PLL1_TUN_RST;
165
s->regs[REG_INDEX(REG_PLL2_CFG)] = REG_PLL2_CFG_RST;
166
s->regs[REG_INDEX(REG_PLL2_TUN)] = REG_PLL2_TUN_RST;
167
s->regs[REG_INDEX(REG_PLL3_CFG)] = REG_PLL3_CFG_RST;
168
s->regs[REG_INDEX(REG_PLL4_CFG)] = REG_PLL4_CFG_RST;
169
s->regs[REG_INDEX(REG_PLL5_CFG)] = REG_PLL5_CFG_RST;
170
s->regs[REG_INDEX(REG_PLL5_TUN)] = REG_PLL5_TUN_RST;
171
s->regs[REG_INDEX(REG_PLL6_CFG)] = REG_PLL6_CFG_RST;
172
s->regs[REG_INDEX(REG_PLL6_TUN)] = REG_PLL6_TUN_RST;
173
s->regs[REG_INDEX(REG_PLL7_CFG)] = REG_PLL7_CFG_RST;
174
s->regs[REG_INDEX(REG_PLL1_TUN2)] = REG_PLL1_TUN2_RST;
175
s->regs[REG_INDEX(REG_PLL5_TUN2)] = REG_PLL5_TUN2_RST;
176
s->regs[REG_INDEX(REG_PLL8_CFG)] = REG_PLL8_CFG_RST;
177
s->regs[REG_INDEX(REG_OSC24M_CFG)] = REG_OSC24M_CFG_RST;
178
s->regs[REG_INDEX(REG_CPU_AHB_APB0_CFG)] = REG_CPU_AHB_APB0_CFG_RST;
181
static void allwinner_a10_ccm_init(Object *obj)
183
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
184
AwA10ClockCtlState *s = AW_A10_CCM(obj);
187
memory_region_init_io(&s->iomem, OBJECT(s), &allwinner_a10_ccm_ops, s,
188
TYPE_AW_A10_CCM, AW_A10_CCM_IOSIZE);
189
sysbus_init_mmio(sbd, &s->iomem);
192
static const VMStateDescription allwinner_a10_ccm_vmstate = {
193
.name = "allwinner-a10-ccm",
195
.minimum_version_id = 1,
196
.fields = (const VMStateField[]) {
197
VMSTATE_UINT32_ARRAY(regs, AwA10ClockCtlState, AW_A10_CCM_REGS_NUM),
198
VMSTATE_END_OF_LIST()
202
static void allwinner_a10_ccm_class_init(ObjectClass *klass, void *data)
204
DeviceClass *dc = DEVICE_CLASS(klass);
205
ResettableClass *rc = RESETTABLE_CLASS(klass);
207
rc->phases.enter = allwinner_a10_ccm_reset_enter;
208
dc->vmsd = &allwinner_a10_ccm_vmstate;
211
static const TypeInfo allwinner_a10_ccm_info = {
212
.name = TYPE_AW_A10_CCM,
213
.parent = TYPE_SYS_BUS_DEVICE,
214
.instance_init = allwinner_a10_ccm_init,
215
.instance_size = sizeof(AwA10ClockCtlState),
216
.class_init = allwinner_a10_ccm_class_init,
219
static void allwinner_a10_ccm_register(void)
221
type_register_static(&allwinner_a10_ccm_info);
224
type_init(allwinner_a10_ccm_register)