9pfs: factor out virtio_9p_push_and_notify
[qemu/ar7.git] / hw / misc / imx31_ccm.c
blobb92d2e0392ba61eef1bd11db9bc3bc70780334d0
1 /*
2 * IMX31 Clock Control Module
4 * Copyright (C) 2012 NICTA
5 * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
7 * This work is licensed under the terms of the GNU GPL, version 2 or later.
8 * See the COPYING file in the top-level directory.
10 * To get the timer frequencies right, we need to emulate at least part of
11 * the i.MX31 CCM.
14 #include "hw/misc/imx31_ccm.h"
16 #define CKIH_FREQ 26000000 /* 26MHz crystal input */
18 #ifndef DEBUG_IMX31_CCM
19 #define DEBUG_IMX31_CCM 0
20 #endif
22 #define DPRINTF(fmt, args...) \
23 do { \
24 if (DEBUG_IMX31_CCM) { \
25 fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX31_CCM, \
26 __func__, ##args); \
27 } \
28 } while (0)
30 static char const *imx31_ccm_reg_name(uint32_t reg)
32 switch (reg) {
33 case 0:
34 return "CCMR";
35 case 1:
36 return "PDR0";
37 case 2:
38 return "PDR1";
39 case 3:
40 return "RCSR";
41 case 4:
42 return "MPCTL";
43 case 5:
44 return "UPCTL";
45 case 6:
46 return "SPCTL";
47 case 7:
48 return "COSR";
49 case 8:
50 return "CGR0";
51 case 9:
52 return "CGR1";
53 case 10:
54 return "CGR2";
55 case 11:
56 return "WIMR";
57 case 12:
58 return "LDC";
59 case 13:
60 return "DCVR0";
61 case 14:
62 return "DCVR1";
63 case 15:
64 return "DCVR2";
65 case 16:
66 return "DCVR3";
67 case 17:
68 return "LTR0";
69 case 18:
70 return "LTR1";
71 case 19:
72 return "LTR2";
73 case 20:
74 return "LTR3";
75 case 21:
76 return "LTBR0";
77 case 22:
78 return "LTBR1";
79 case 23:
80 return "PMCR0";
81 case 24:
82 return "PMCR1";
83 case 25:
84 return "PDR2";
85 default:
86 return "???";
90 static const VMStateDescription vmstate_imx31_ccm = {
91 .name = TYPE_IMX31_CCM,
92 .version_id = 1,
93 .minimum_version_id = 1,
94 .fields = (VMStateField[]) {
95 VMSTATE_UINT32(ccmr, IMX31CCMState),
96 VMSTATE_UINT32(pdr0, IMX31CCMState),
97 VMSTATE_UINT32(pdr1, IMX31CCMState),
98 VMSTATE_UINT32(mpctl, IMX31CCMState),
99 VMSTATE_UINT32(spctl, IMX31CCMState),
100 VMSTATE_UINT32_ARRAY(cgr, IMX31CCMState, 3),
101 VMSTATE_UINT32(pmcr0, IMX31CCMState),
102 VMSTATE_UINT32(pmcr1, IMX31CCMState),
103 VMSTATE_END_OF_LIST()
107 static uint32_t imx31_ccm_get_pll_ref_clk(IMXCCMState *dev)
109 uint32_t freq = 0;
110 IMX31CCMState *s = IMX31_CCM(dev);
112 if ((s->ccmr & CCMR_PRCS) == 2) {
113 if (s->ccmr & CCMR_FPME) {
114 freq = CKIL_FREQ;
115 if (s->ccmr & CCMR_FPMF) {
116 freq *= 1024;
119 } else {
120 freq = CKIH_FREQ;
123 DPRINTF("freq = %d\n", freq);
125 return freq;
128 static uint32_t imx31_ccm_get_mpll_clk(IMXCCMState *dev)
130 uint32_t freq;
131 IMX31CCMState *s = IMX31_CCM(dev);
133 freq = imx_ccm_calc_pll(s->mpctl, imx31_ccm_get_pll_ref_clk(dev));
135 DPRINTF("freq = %d\n", freq);
137 return freq;
140 static uint32_t imx31_ccm_get_mcu_main_clk(IMXCCMState *dev)
142 uint32_t freq;
143 IMX31CCMState *s = IMX31_CCM(dev);
145 if ((s->ccmr & CCMR_MDS) || !(s->ccmr & CCMR_MPE)) {
146 freq = imx31_ccm_get_pll_ref_clk(dev);
147 } else {
148 freq = imx31_ccm_get_mpll_clk(dev);
151 DPRINTF("freq = %d\n", freq);
153 return freq;
156 static uint32_t imx31_ccm_get_mcu_clk(IMXCCMState *dev)
158 uint32_t freq;
159 IMX31CCMState *s = IMX31_CCM(dev);
161 freq = imx31_ccm_get_mcu_main_clk(dev) / (1 + EXTRACT(s->pdr0, MCU));
163 DPRINTF("freq = %d\n", freq);
165 return freq;
168 static uint32_t imx31_ccm_get_hsp_clk(IMXCCMState *dev)
170 uint32_t freq;
171 IMX31CCMState *s = IMX31_CCM(dev);
173 freq = imx31_ccm_get_mcu_main_clk(dev) / (1 + EXTRACT(s->pdr0, HSP));
175 DPRINTF("freq = %d\n", freq);
177 return freq;
180 static uint32_t imx31_ccm_get_hclk_clk(IMXCCMState *dev)
182 uint32_t freq;
183 IMX31CCMState *s = IMX31_CCM(dev);
185 freq = imx31_ccm_get_mcu_main_clk(dev) / (1 + EXTRACT(s->pdr0, MAX));
187 DPRINTF("freq = %d\n", freq);
189 return freq;
192 static uint32_t imx31_ccm_get_ipg_clk(IMXCCMState *dev)
194 uint32_t freq;
195 IMX31CCMState *s = IMX31_CCM(dev);
197 freq = imx31_ccm_get_hclk_clk(dev) / (1 + EXTRACT(s->pdr0, IPG));
199 DPRINTF("freq = %d\n", freq);
201 return freq;
204 static uint32_t imx31_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
206 uint32_t freq = 0;
208 switch (clock) {
209 case NOCLK:
210 break;
211 case CLK_MCU:
212 freq = imx31_ccm_get_mcu_clk(dev);
213 break;
214 case CLK_HSP:
215 freq = imx31_ccm_get_hsp_clk(dev);
216 break;
217 case CLK_IPG:
218 freq = imx31_ccm_get_ipg_clk(dev);
219 break;
220 case CLK_32k:
221 freq = CKIL_FREQ;
222 break;
223 default:
224 qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: unsupported clock %d\n",
225 TYPE_IMX31_CCM, __func__, clock);
226 break;
229 DPRINTF("Clock = %d) = %d\n", clock, freq);
231 return freq;
234 static void imx31_ccm_reset(DeviceState *dev)
236 IMX31CCMState *s = IMX31_CCM(dev);
238 DPRINTF("()\n");
240 s->ccmr = 0x074b0b7d;
241 s->pdr0 = 0xff870b48;
242 s->pdr1 = 0x49fcfe7f;
243 s->mpctl = 0x04001800;
244 s->cgr[0] = s->cgr[1] = s->cgr[2] = 0xffffffff;
245 s->spctl = 0x04043001;
246 s->pmcr0 = 0x80209828;
247 s->pmcr1 = 0x00aa0000;
250 static uint64_t imx31_ccm_read(void *opaque, hwaddr offset, unsigned size)
252 uint32 value = 0;
253 IMX31CCMState *s = (IMX31CCMState *)opaque;
255 switch (offset >> 2) {
256 case 0: /* CCMR */
257 value = s->ccmr;
258 break;
259 case 1:
260 value = s->pdr0;
261 break;
262 case 2:
263 value = s->pdr1;
264 break;
265 case 4:
266 value = s->mpctl;
267 break;
268 case 6:
269 value = s->spctl;
270 break;
271 case 8:
272 value = s->cgr[0];
273 break;
274 case 9:
275 value = s->cgr[1];
276 break;
277 case 10:
278 value = s->cgr[2];
279 break;
280 case 18: /* LTR1 */
281 value = 0x00004040;
282 break;
283 case 23:
284 value = s->pmcr0;
285 break;
286 default:
287 qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
288 HWADDR_PRIx "\n", TYPE_IMX31_CCM, __func__, offset);
289 break;
292 DPRINTF("reg[%s] => 0x%" PRIx32 "\n", imx31_ccm_reg_name(offset >> 2),
293 value);
295 return (uint64_t)value;
298 static void imx31_ccm_write(void *opaque, hwaddr offset, uint64_t value,
299 unsigned size)
301 IMX31CCMState *s = (IMX31CCMState *)opaque;
303 DPRINTF("reg[%s] <= 0x%" PRIx32 "\n", imx31_ccm_reg_name(offset >> 2),
304 (uint32_t)value);
306 switch (offset >> 2) {
307 case 0:
308 s->ccmr = CCMR_FPMF | (value & 0x3b6fdfff);
309 break;
310 case 1:
311 s->pdr0 = value & 0xff9f3fff;
312 break;
313 case 2:
314 s->pdr1 = value;
315 break;
316 case 4:
317 s->mpctl = value & 0xbfff3fff;
318 break;
319 case 6:
320 s->spctl = value & 0xbfff3fff;
321 break;
322 case 8:
323 s->cgr[0] = value;
324 break;
325 case 9:
326 s->cgr[1] = value;
327 break;
328 case 10:
329 s->cgr[2] = value;
330 break;
331 default:
332 qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
333 HWADDR_PRIx "\n", TYPE_IMX31_CCM, __func__, offset);
334 break;
338 static const struct MemoryRegionOps imx31_ccm_ops = {
339 .read = imx31_ccm_read,
340 .write = imx31_ccm_write,
341 .endianness = DEVICE_NATIVE_ENDIAN,
342 .valid = {
344 * Our device would not work correctly if the guest was doing
345 * unaligned access. This might not be a limitation on the real
346 * device but in practice there is no reason for a guest to access
347 * this device unaligned.
349 .min_access_size = 4,
350 .max_access_size = 4,
351 .unaligned = false,
356 static void imx31_ccm_init(Object *obj)
358 DeviceState *dev = DEVICE(obj);
359 SysBusDevice *sd = SYS_BUS_DEVICE(obj);
360 IMX31CCMState *s = IMX31_CCM(obj);
362 memory_region_init_io(&s->iomem, OBJECT(dev), &imx31_ccm_ops, s,
363 TYPE_IMX31_CCM, 0x1000);
364 sysbus_init_mmio(sd, &s->iomem);
367 static void imx31_ccm_class_init(ObjectClass *klass, void *data)
369 DeviceClass *dc = DEVICE_CLASS(klass);
370 IMXCCMClass *ccm = IMX_CCM_CLASS(klass);
372 dc->reset = imx31_ccm_reset;
373 dc->vmsd = &vmstate_imx31_ccm;
374 dc->desc = "i.MX31 Clock Control Module";
376 ccm->get_clock_frequency = imx31_ccm_get_clock_frequency;
379 static const TypeInfo imx31_ccm_info = {
380 .name = TYPE_IMX31_CCM,
381 .parent = TYPE_IMX_CCM,
382 .instance_size = sizeof(IMX31CCMState),
383 .instance_init = imx31_ccm_init,
384 .class_init = imx31_ccm_class_init,
387 static void imx31_ccm_register_types(void)
389 type_register_static(&imx31_ccm_info);
392 type_init(imx31_ccm_register_types)