12
#include "qemu/osdep.h"
14
#include "qemu/module.h"
16
#include "hw/misc/imx7_ccm.h"
17
#include "migration/vmstate.h"
21
#define CKIH_FREQ 24000000
23
static void imx7_analog_reset(DeviceState *dev)
25
IMX7AnalogState *s = IMX7_ANALOG(dev);
27
memset(s->pmu, 0, sizeof(s->pmu));
28
memset(s->analog, 0, sizeof(s->analog));
30
s->analog[ANALOG_PLL_ARM] = 0x00002042;
31
s->analog[ANALOG_PLL_DDR] = 0x0060302c;
32
s->analog[ANALOG_PLL_DDR_SS] = 0x00000000;
33
s->analog[ANALOG_PLL_DDR_NUM] = 0x06aaac4d;
34
s->analog[ANALOG_PLL_DDR_DENOM] = 0x100003ec;
35
s->analog[ANALOG_PLL_480] = 0x00002000;
36
s->analog[ANALOG_PLL_480A] = 0x52605a56;
37
s->analog[ANALOG_PLL_480B] = 0x52525216;
38
s->analog[ANALOG_PLL_ENET] = 0x00001fc0;
39
s->analog[ANALOG_PLL_AUDIO] = 0x0001301b;
40
s->analog[ANALOG_PLL_AUDIO_SS] = 0x00000000;
41
s->analog[ANALOG_PLL_AUDIO_NUM] = 0x05f5e100;
42
s->analog[ANALOG_PLL_AUDIO_DENOM] = 0x2964619c;
43
s->analog[ANALOG_PLL_VIDEO] = 0x0008201b;
44
s->analog[ANALOG_PLL_VIDEO_SS] = 0x00000000;
45
s->analog[ANALOG_PLL_VIDEO_NUM] = 0x0000f699;
46
s->analog[ANALOG_PLL_VIDEO_DENOM] = 0x000f4240;
47
s->analog[ANALOG_PLL_MISC0] = 0x00000000;
50
s->analog[ANALOG_PLL_ARM] |= ANALOG_PLL_LOCK;
51
s->analog[ANALOG_PLL_DDR] |= ANALOG_PLL_LOCK;
52
s->analog[ANALOG_PLL_480] |= ANALOG_PLL_LOCK;
53
s->analog[ANALOG_PLL_480A] |= ANALOG_PLL_LOCK;
54
s->analog[ANALOG_PLL_480B] |= ANALOG_PLL_LOCK;
55
s->analog[ANALOG_PLL_ENET] |= ANALOG_PLL_LOCK;
56
s->analog[ANALOG_PLL_AUDIO] |= ANALOG_PLL_LOCK;
57
s->analog[ANALOG_PLL_VIDEO] |= ANALOG_PLL_LOCK;
58
s->analog[ANALOG_PLL_MISC0] |= ANALOG_PLL_LOCK;
65
s->analog[ANALOG_DIGPROG] = 0x720000;
70
s->analog[ANALOG_DIGPROG] |= 0x000010;
73
static void imx7_ccm_reset(DeviceState *dev)
75
IMX7CCMState *s = IMX7_CCM(dev);
77
memset(s->ccm, 0, sizeof(s->ccm));
80
#define CCM_INDEX(offset) (((offset) & ~(hwaddr)0xF) / sizeof(uint32_t))
81
#define CCM_BITOP(offset) ((offset) & (hwaddr)0xF)
84
CCM_BITOP_NONE = 0x00,
90
static uint64_t imx7_set_clr_tog_read(void *opaque, hwaddr offset,
93
const uint32_t *mmio = opaque;
95
return mmio[CCM_INDEX(offset)];
98
static void imx7_set_clr_tog_write(void *opaque, hwaddr offset,
99
uint64_t value, unsigned size)
101
const uint8_t bitop = CCM_BITOP(offset);
102
const uint32_t index = CCM_INDEX(offset);
103
uint32_t *mmio = opaque;
110
mmio[index] |= value;
113
mmio[index] &= ~value;
116
mmio[index] ^= value;
121
static const struct MemoryRegionOps imx7_set_clr_tog_ops = {
122
.read = imx7_set_clr_tog_read,
123
.write = imx7_set_clr_tog_write,
124
.endianness = DEVICE_NATIVE_ENDIAN,
132
.min_access_size = 4,
133
.max_access_size = 4,
138
static void imx7_digprog_write(void *opaque, hwaddr addr,
139
uint64_t data, unsigned size)
141
qemu_log_mask(LOG_GUEST_ERROR,
142
"Guest write to read-only ANALOG_DIGPROG register\n");
145
static const struct MemoryRegionOps imx7_digprog_ops = {
146
.read = imx7_set_clr_tog_read,
147
.write = imx7_digprog_write,
148
.endianness = DEVICE_NATIVE_ENDIAN,
150
.min_access_size = 4,
151
.max_access_size = 4,
156
static void imx7_ccm_init(Object *obj)
158
SysBusDevice *sd = SYS_BUS_DEVICE(obj);
159
IMX7CCMState *s = IMX7_CCM(obj);
161
memory_region_init_io(&s->iomem,
163
&imx7_set_clr_tog_ops,
165
TYPE_IMX7_CCM ".ccm",
168
sysbus_init_mmio(sd, &s->iomem);
171
static void imx7_analog_init(Object *obj)
173
SysBusDevice *sd = SYS_BUS_DEVICE(obj);
174
IMX7AnalogState *s = IMX7_ANALOG(obj);
176
memory_region_init(&s->mmio.container, obj, TYPE_IMX7_ANALOG,
179
memory_region_init_io(&s->mmio.analog,
181
&imx7_set_clr_tog_ops,
186
memory_region_add_subregion(&s->mmio.container,
187
0x60, &s->mmio.analog);
189
memory_region_init_io(&s->mmio.pmu,
191
&imx7_set_clr_tog_ops,
193
TYPE_IMX7_ANALOG ".pmu",
196
memory_region_add_subregion(&s->mmio.container,
197
0x200, &s->mmio.pmu);
199
memory_region_init_io(&s->mmio.digprog,
202
&s->analog[ANALOG_DIGPROG],
203
TYPE_IMX7_ANALOG ".digprog",
206
memory_region_add_subregion_overlap(&s->mmio.container,
207
0x800, &s->mmio.digprog, 10);
210
sysbus_init_mmio(sd, &s->mmio.container);
213
static const VMStateDescription vmstate_imx7_ccm = {
214
.name = TYPE_IMX7_CCM,
216
.minimum_version_id = 1,
217
.fields = (const VMStateField[]) {
218
VMSTATE_UINT32_ARRAY(ccm, IMX7CCMState, CCM_MAX),
219
VMSTATE_END_OF_LIST()
223
static uint32_t imx7_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
251
qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Clock %d Not implemented\n",
252
TYPE_IMX7_CCM, __func__, clock);
255
qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: unsupported clock %d\n",
256
TYPE_IMX7_CCM, __func__, clock);
260
trace_ccm_clock_freq(clock, freq);
265
static void imx7_ccm_class_init(ObjectClass *klass, void *data)
267
DeviceClass *dc = DEVICE_CLASS(klass);
268
IMXCCMClass *ccm = IMX_CCM_CLASS(klass);
270
dc->reset = imx7_ccm_reset;
271
dc->vmsd = &vmstate_imx7_ccm;
272
dc->desc = "i.MX7 Clock Control Module";
274
ccm->get_clock_frequency = imx7_ccm_get_clock_frequency;
277
static const TypeInfo imx7_ccm_info = {
278
.name = TYPE_IMX7_CCM,
279
.parent = TYPE_IMX_CCM,
280
.instance_size = sizeof(IMX7CCMState),
281
.instance_init = imx7_ccm_init,
282
.class_init = imx7_ccm_class_init,
285
static const VMStateDescription vmstate_imx7_analog = {
286
.name = TYPE_IMX7_ANALOG,
288
.minimum_version_id = 1,
289
.fields = (const VMStateField[]) {
290
VMSTATE_UINT32_ARRAY(analog, IMX7AnalogState, ANALOG_MAX),
291
VMSTATE_UINT32_ARRAY(pmu, IMX7AnalogState, PMU_MAX),
292
VMSTATE_END_OF_LIST()
296
static void imx7_analog_class_init(ObjectClass *klass, void *data)
298
DeviceClass *dc = DEVICE_CLASS(klass);
300
dc->reset = imx7_analog_reset;
301
dc->vmsd = &vmstate_imx7_analog;
302
dc->desc = "i.MX7 Analog Module";
305
static const TypeInfo imx7_analog_info = {
306
.name = TYPE_IMX7_ANALOG,
307
.parent = TYPE_SYS_BUS_DEVICE,
308
.instance_size = sizeof(IMX7AnalogState),
309
.instance_init = imx7_analog_init,
310
.class_init = imx7_analog_class_init,
313
static void imx7_ccm_register_type(void)
315
type_register_static(&imx7_ccm_info);
316
type_register_static(&imx7_analog_info);
318
type_init(imx7_ccm_register_type)