xref: /openbmc/qemu/hw/misc/imx6ul_ccm.c (revision 6016b7b4)
1 /*
2  * IMX6UL Clock Control Module
3  *
4  * Copyright (c) 2018 Jean-Christophe Dubois <jcd@tribudubois.net>
5  *
6  * This work is licensed under the terms of the GNU GPL, version 2 or later.
7  * See the COPYING file in the top-level directory.
8  *
9  * To get the timer frequencies right, we need to emulate at least part of
10  * the CCM.
11  */
12 
13 #include "qemu/osdep.h"
14 #include "hw/registerfields.h"
15 #include "migration/vmstate.h"
16 #include "hw/misc/imx6ul_ccm.h"
17 #include "qemu/log.h"
18 #include "qemu/module.h"
19 
20 #include "trace.h"
21 
22 static const uint32_t ccm_mask[CCM_MAX] = {
23     [CCM_CCR] = 0xf01fef80,
24     [CCM_CCDR] = 0xfffeffff,
25     [CCM_CSR] = 0xffffffff,
26     [CCM_CCSR] = 0xfffffef2,
27     [CCM_CACRR] = 0xfffffff8,
28     [CCM_CBCDR] = 0xc1f8e000,
29     [CCM_CBCMR] = 0xfc03cfff,
30     [CCM_CSCMR1] = 0x80700000,
31     [CCM_CSCMR2] = 0xe01ff003,
32     [CCM_CSCDR1] = 0xfe00c780,
33     [CCM_CS1CDR] = 0xfe00fe00,
34     [CCM_CS2CDR] = 0xf8007000,
35     [CCM_CDCDR] = 0xf00fffff,
36     [CCM_CHSCCDR] = 0xfffc01ff,
37     [CCM_CSCDR2] = 0xfe0001ff,
38     [CCM_CSCDR3] = 0xffffc1ff,
39     [CCM_CDHIPR] = 0xffffffff,
40     [CCM_CTOR] = 0x00000000,
41     [CCM_CLPCR] = 0xf39ff01c,
42     [CCM_CISR] = 0xfb85ffbe,
43     [CCM_CIMR] = 0xfb85ffbf,
44     [CCM_CCOSR] = 0xfe00fe00,
45     [CCM_CGPR] = 0xfffc3fea,
46     [CCM_CCGR0] = 0x00000000,
47     [CCM_CCGR1] = 0x00000000,
48     [CCM_CCGR2] = 0x00000000,
49     [CCM_CCGR3] = 0x00000000,
50     [CCM_CCGR4] = 0x00000000,
51     [CCM_CCGR5] = 0x00000000,
52     [CCM_CCGR6] = 0x00000000,
53     [CCM_CMEOR] = 0xafffff1f,
54 };
55 
56 static const uint32_t analog_mask[CCM_ANALOG_MAX] = {
57     [CCM_ANALOG_PLL_ARM] = 0xfff60f80,
58     [CCM_ANALOG_PLL_USB1] = 0xfffe0fbc,
59     [CCM_ANALOG_PLL_USB2] = 0xfffe0fbc,
60     [CCM_ANALOG_PLL_SYS] = 0xfffa0ffe,
61     [CCM_ANALOG_PLL_SYS_SS] = 0x00000000,
62     [CCM_ANALOG_PLL_SYS_NUM] = 0xc0000000,
63     [CCM_ANALOG_PLL_SYS_DENOM] = 0xc0000000,
64     [CCM_ANALOG_PLL_AUDIO] = 0xffe20f80,
65     [CCM_ANALOG_PLL_AUDIO_NUM] = 0xc0000000,
66     [CCM_ANALOG_PLL_AUDIO_DENOM] = 0xc0000000,
67     [CCM_ANALOG_PLL_VIDEO] = 0xffe20f80,
68     [CCM_ANALOG_PLL_VIDEO_NUM] = 0xc0000000,
69     [CCM_ANALOG_PLL_VIDEO_DENOM] = 0xc0000000,
70     [CCM_ANALOG_PLL_ENET] = 0xffc20ff0,
71     [CCM_ANALOG_PFD_480] = 0x40404040,
72     [CCM_ANALOG_PFD_528] = 0x40404040,
73     [PMU_MISC0] = 0x01fe8306,
74     [PMU_MISC1] = 0x07fcede0,
75     [PMU_MISC2] = 0x005f5f5f,
76 };
77 
78 static const char *imx6ul_ccm_reg_name(uint32_t reg)
79 {
80     static char unknown[20];
81 
82     switch (reg) {
83     case CCM_CCR:
84         return "CCR";
85     case CCM_CCDR:
86         return "CCDR";
87     case CCM_CSR:
88         return "CSR";
89     case CCM_CCSR:
90         return "CCSR";
91     case CCM_CACRR:
92         return "CACRR";
93     case CCM_CBCDR:
94         return "CBCDR";
95     case CCM_CBCMR:
96         return "CBCMR";
97     case CCM_CSCMR1:
98         return "CSCMR1";
99     case CCM_CSCMR2:
100         return "CSCMR2";
101     case CCM_CSCDR1:
102         return "CSCDR1";
103     case CCM_CS1CDR:
104         return "CS1CDR";
105     case CCM_CS2CDR:
106         return "CS2CDR";
107     case CCM_CDCDR:
108         return "CDCDR";
109     case CCM_CHSCCDR:
110         return "CHSCCDR";
111     case CCM_CSCDR2:
112         return "CSCDR2";
113     case CCM_CSCDR3:
114         return "CSCDR3";
115     case CCM_CDHIPR:
116         return "CDHIPR";
117     case CCM_CTOR:
118         return "CTOR";
119     case CCM_CLPCR:
120         return "CLPCR";
121     case CCM_CISR:
122         return "CISR";
123     case CCM_CIMR:
124         return "CIMR";
125     case CCM_CCOSR:
126         return "CCOSR";
127     case CCM_CGPR:
128         return "CGPR";
129     case CCM_CCGR0:
130         return "CCGR0";
131     case CCM_CCGR1:
132         return "CCGR1";
133     case CCM_CCGR2:
134         return "CCGR2";
135     case CCM_CCGR3:
136         return "CCGR3";
137     case CCM_CCGR4:
138         return "CCGR4";
139     case CCM_CCGR5:
140         return "CCGR5";
141     case CCM_CCGR6:
142         return "CCGR6";
143     case CCM_CMEOR:
144         return "CMEOR";
145     default:
146         sprintf(unknown, "%u ?", reg);
147         return unknown;
148     }
149 }
150 
151 static const char *imx6ul_analog_reg_name(uint32_t reg)
152 {
153     static char unknown[20];
154 
155     switch (reg) {
156     case CCM_ANALOG_PLL_ARM:
157         return "PLL_ARM";
158     case CCM_ANALOG_PLL_ARM_SET:
159         return "PLL_ARM_SET";
160     case CCM_ANALOG_PLL_ARM_CLR:
161         return "PLL_ARM_CLR";
162     case CCM_ANALOG_PLL_ARM_TOG:
163         return "PLL_ARM_TOG";
164     case CCM_ANALOG_PLL_USB1:
165         return "PLL_USB1";
166     case CCM_ANALOG_PLL_USB1_SET:
167         return "PLL_USB1_SET";
168     case CCM_ANALOG_PLL_USB1_CLR:
169         return "PLL_USB1_CLR";
170     case CCM_ANALOG_PLL_USB1_TOG:
171         return "PLL_USB1_TOG";
172     case CCM_ANALOG_PLL_USB2:
173         return "PLL_USB2";
174     case CCM_ANALOG_PLL_USB2_SET:
175         return "PLL_USB2_SET";
176     case CCM_ANALOG_PLL_USB2_CLR:
177         return "PLL_USB2_CLR";
178     case CCM_ANALOG_PLL_USB2_TOG:
179         return "PLL_USB2_TOG";
180     case CCM_ANALOG_PLL_SYS:
181         return "PLL_SYS";
182     case CCM_ANALOG_PLL_SYS_SET:
183         return "PLL_SYS_SET";
184     case CCM_ANALOG_PLL_SYS_CLR:
185         return "PLL_SYS_CLR";
186     case CCM_ANALOG_PLL_SYS_TOG:
187         return "PLL_SYS_TOG";
188     case CCM_ANALOG_PLL_SYS_SS:
189         return "PLL_SYS_SS";
190     case CCM_ANALOG_PLL_SYS_NUM:
191         return "PLL_SYS_NUM";
192     case CCM_ANALOG_PLL_SYS_DENOM:
193         return "PLL_SYS_DENOM";
194     case CCM_ANALOG_PLL_AUDIO:
195         return "PLL_AUDIO";
196     case CCM_ANALOG_PLL_AUDIO_SET:
197         return "PLL_AUDIO_SET";
198     case CCM_ANALOG_PLL_AUDIO_CLR:
199         return "PLL_AUDIO_CLR";
200     case CCM_ANALOG_PLL_AUDIO_TOG:
201         return "PLL_AUDIO_TOG";
202     case CCM_ANALOG_PLL_AUDIO_NUM:
203         return "PLL_AUDIO_NUM";
204     case CCM_ANALOG_PLL_AUDIO_DENOM:
205         return "PLL_AUDIO_DENOM";
206     case CCM_ANALOG_PLL_VIDEO:
207         return "PLL_VIDEO";
208     case CCM_ANALOG_PLL_VIDEO_SET:
209         return "PLL_VIDEO_SET";
210     case CCM_ANALOG_PLL_VIDEO_CLR:
211         return "PLL_VIDEO_CLR";
212     case CCM_ANALOG_PLL_VIDEO_TOG:
213         return "PLL_VIDEO_TOG";
214     case CCM_ANALOG_PLL_VIDEO_NUM:
215         return "PLL_VIDEO_NUM";
216     case CCM_ANALOG_PLL_VIDEO_DENOM:
217         return "PLL_VIDEO_DENOM";
218     case CCM_ANALOG_PLL_ENET:
219         return "PLL_ENET";
220     case CCM_ANALOG_PLL_ENET_SET:
221         return "PLL_ENET_SET";
222     case CCM_ANALOG_PLL_ENET_CLR:
223         return "PLL_ENET_CLR";
224     case CCM_ANALOG_PLL_ENET_TOG:
225         return "PLL_ENET_TOG";
226     case CCM_ANALOG_PFD_480:
227         return "PFD_480";
228     case CCM_ANALOG_PFD_480_SET:
229         return "PFD_480_SET";
230     case CCM_ANALOG_PFD_480_CLR:
231         return "PFD_480_CLR";
232     case CCM_ANALOG_PFD_480_TOG:
233         return "PFD_480_TOG";
234     case CCM_ANALOG_PFD_528:
235         return "PFD_528";
236     case CCM_ANALOG_PFD_528_SET:
237         return "PFD_528_SET";
238     case CCM_ANALOG_PFD_528_CLR:
239         return "PFD_528_CLR";
240     case CCM_ANALOG_PFD_528_TOG:
241         return "PFD_528_TOG";
242     case CCM_ANALOG_MISC0:
243         return "MISC0";
244     case CCM_ANALOG_MISC0_SET:
245         return "MISC0_SET";
246     case CCM_ANALOG_MISC0_CLR:
247         return "MISC0_CLR";
248     case CCM_ANALOG_MISC0_TOG:
249         return "MISC0_TOG";
250     case CCM_ANALOG_MISC2:
251         return "MISC2";
252     case CCM_ANALOG_MISC2_SET:
253         return "MISC2_SET";
254     case CCM_ANALOG_MISC2_CLR:
255         return "MISC2_CLR";
256     case CCM_ANALOG_MISC2_TOG:
257         return "MISC2_TOG";
258     case PMU_REG_1P1:
259         return "PMU_REG_1P1";
260     case PMU_REG_3P0:
261         return "PMU_REG_3P0";
262     case PMU_REG_2P5:
263         return "PMU_REG_2P5";
264     case PMU_REG_CORE:
265         return "PMU_REG_CORE";
266     case PMU_MISC1:
267         return "PMU_MISC1";
268     case PMU_MISC1_SET:
269         return "PMU_MISC1_SET";
270     case PMU_MISC1_CLR:
271         return "PMU_MISC1_CLR";
272     case PMU_MISC1_TOG:
273         return "PMU_MISC1_TOG";
274     case USB_ANALOG_DIGPROG:
275         return "USB_ANALOG_DIGPROG";
276     default:
277         sprintf(unknown, "%u ?", reg);
278         return unknown;
279     }
280 }
281 
282 #define CKIH_FREQ 24000000 /* 24MHz crystal input */
283 
284 static const VMStateDescription vmstate_imx6ul_ccm = {
285     .name = TYPE_IMX6UL_CCM,
286     .version_id = 1,
287     .minimum_version_id = 1,
288     .fields = (VMStateField[]) {
289         VMSTATE_UINT32_ARRAY(ccm, IMX6ULCCMState, CCM_MAX),
290         VMSTATE_UINT32_ARRAY(analog, IMX6ULCCMState, CCM_ANALOG_MAX),
291         VMSTATE_END_OF_LIST()
292     },
293 };
294 
295 static uint64_t imx6ul_analog_get_osc_clk(IMX6ULCCMState *dev)
296 {
297     uint64_t freq = CKIH_FREQ;
298 
299     trace_ccm_freq((uint32_t)freq);
300 
301     return freq;
302 }
303 
304 static uint64_t imx6ul_analog_get_pll2_clk(IMX6ULCCMState *dev)
305 {
306     uint64_t freq = imx6ul_analog_get_osc_clk(dev);
307 
308     if (FIELD_EX32(dev->analog[CCM_ANALOG_PLL_SYS],
309                    ANALOG_PLL_SYS, DIV_SELECT)) {
310         freq *= 22;
311     } else {
312         freq *= 20;
313     }
314 
315     trace_ccm_freq((uint32_t)freq);
316 
317     return freq;
318 }
319 
320 static uint64_t imx6ul_analog_get_pll3_clk(IMX6ULCCMState *dev)
321 {
322     uint64_t freq = imx6ul_analog_get_osc_clk(dev) * 20;
323 
324     trace_ccm_freq((uint32_t)freq);
325 
326     return freq;
327 }
328 
329 static uint64_t imx6ul_analog_get_pll2_pfd0_clk(IMX6ULCCMState *dev)
330 {
331     uint64_t freq = 0;
332 
333     freq = imx6ul_analog_get_pll2_clk(dev) * 18
334            / FIELD_EX32(dev->analog[CCM_ANALOG_PFD_528],
335                         ANALOG_PFD_528, PFD0_FRAC);
336 
337     trace_ccm_freq((uint32_t)freq);
338 
339     return freq;
340 }
341 
342 static uint64_t imx6ul_analog_get_pll2_pfd2_clk(IMX6ULCCMState *dev)
343 {
344     uint64_t freq = 0;
345 
346     freq = imx6ul_analog_get_pll2_clk(dev) * 18
347            / FIELD_EX32(dev->analog[CCM_ANALOG_PFD_528],
348                         ANALOG_PFD_528, PFD2_FRAC);
349 
350     trace_ccm_freq((uint32_t)freq);
351 
352     return freq;
353 }
354 
355 static uint64_t imx6ul_analog_pll2_bypass_clk(IMX6ULCCMState *dev)
356 {
357     uint64_t freq = 0;
358 
359     trace_ccm_freq((uint32_t)freq);
360 
361     return freq;
362 }
363 
364 static uint64_t imx6ul_ccm_get_periph_clk2_sel_clk(IMX6ULCCMState *dev)
365 {
366     uint64_t freq = 0;
367 
368     switch (FIELD_EX32(dev->ccm[CCM_CBCMR], CBCMR, PERIPH_CLK2_SEL)) {
369     case 0:
370         freq = imx6ul_analog_get_pll3_clk(dev);
371         break;
372     case 1:
373         freq = imx6ul_analog_get_osc_clk(dev);
374         break;
375     case 2:
376         freq = imx6ul_analog_pll2_bypass_clk(dev);
377         break;
378     case 3:
379         /* We should never get there as 3 is a reserved value */
380         qemu_log_mask(LOG_GUEST_ERROR,
381                       "[%s]%s: unsupported PERIPH_CLK2_SEL value 3\n",
382                       TYPE_IMX6UL_CCM, __func__);
383         /* freq is set to 0 as we don't know what it should be */
384         break;
385     default:
386         g_assert_not_reached();
387     }
388 
389     trace_ccm_freq((uint32_t)freq);
390 
391     return freq;
392 }
393 
394 static uint64_t imx6ul_ccm_get_periph_clk_sel_clk(IMX6ULCCMState *dev)
395 {
396     uint64_t freq = 0;
397 
398     switch (FIELD_EX32(dev->ccm[CCM_CBCMR], CBCMR, PRE_PERIPH_CLK_SEL)) {
399     case 0:
400         freq = imx6ul_analog_get_pll2_clk(dev);
401         break;
402     case 1:
403         freq = imx6ul_analog_get_pll2_pfd2_clk(dev);
404         break;
405     case 2:
406         freq = imx6ul_analog_get_pll2_pfd0_clk(dev);
407         break;
408     case 3:
409         freq = imx6ul_analog_get_pll2_pfd2_clk(dev) / 2;
410         break;
411     default:
412         g_assert_not_reached();
413     }
414 
415     trace_ccm_freq((uint32_t)freq);
416 
417     return freq;
418 }
419 
420 static uint64_t imx6ul_ccm_get_periph_clk2_clk(IMX6ULCCMState *dev)
421 {
422     uint64_t freq = 0;
423 
424     freq = imx6ul_ccm_get_periph_clk2_sel_clk(dev)
425            / (1 + FIELD_EX32(dev->ccm[CCM_CBCDR], CBCDR, PERIPH_CLK2_PODF));
426 
427     trace_ccm_freq((uint32_t)freq);
428 
429     return freq;
430 }
431 
432 static uint64_t imx6ul_ccm_get_periph_sel_clk(IMX6ULCCMState *dev)
433 {
434     uint64_t freq = 0;
435 
436     switch (FIELD_EX32(dev->ccm[CCM_CBCDR], CBCDR, PERIPH_CLK_SEL)) {
437     case 0:
438         freq = imx6ul_ccm_get_periph_clk_sel_clk(dev);
439         break;
440     case 1:
441         freq = imx6ul_ccm_get_periph_clk2_clk(dev);
442         break;
443     default:
444         g_assert_not_reached();
445     }
446 
447     trace_ccm_freq((uint32_t)freq);
448 
449     return freq;
450 }
451 
452 static uint64_t imx6ul_ccm_get_ahb_clk(IMX6ULCCMState *dev)
453 {
454     uint64_t freq = 0;
455 
456     freq = imx6ul_ccm_get_periph_sel_clk(dev)
457            / (1 + FIELD_EX32(dev->ccm[CCM_CBCDR], CBCDR, AHB_PODF));
458 
459     trace_ccm_freq((uint32_t)freq);
460 
461     return freq;
462 }
463 
464 static uint64_t imx6ul_ccm_get_ipg_clk(IMX6ULCCMState *dev)
465 {
466     uint64_t freq = 0;
467 
468     freq = imx6ul_ccm_get_ahb_clk(dev)
469            / (1 + FIELD_EX32(dev->ccm[CCM_CBCDR], CBCDR, IPG_PODF));
470 
471     trace_ccm_freq((uint32_t)freq);
472 
473     return freq;
474 }
475 
476 static uint64_t imx6ul_ccm_get_per_sel_clk(IMX6ULCCMState *dev)
477 {
478     uint64_t freq = 0;
479 
480     switch (FIELD_EX32(dev->ccm[CCM_CSCMR1], CSCMR1, PERCLK_CLK_SEL)) {
481     case 0:
482         freq = imx6ul_ccm_get_ipg_clk(dev);
483         break;
484     case 1:
485         freq = imx6ul_analog_get_osc_clk(dev);
486         break;
487     default:
488         g_assert_not_reached();
489     }
490 
491     trace_ccm_freq((uint32_t)freq);
492 
493     return freq;
494 }
495 
496 static uint64_t imx6ul_ccm_get_per_clk(IMX6ULCCMState *dev)
497 {
498     uint64_t freq = 0;
499 
500     freq = imx6ul_ccm_get_per_sel_clk(dev)
501            / (1 + FIELD_EX32(dev->ccm[CCM_CSCMR1], CSCMR1, PERCLK_PODF));
502 
503     trace_ccm_freq((uint32_t)freq);
504 
505     return freq;
506 }
507 
508 static uint32_t imx6ul_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
509 {
510     uint32_t freq = 0;
511     IMX6ULCCMState *s = IMX6UL_CCM(dev);
512 
513     switch (clock) {
514     case CLK_NONE:
515         break;
516     case CLK_IPG:
517         freq = imx6ul_ccm_get_ipg_clk(s);
518         break;
519     case CLK_IPG_HIGH:
520         freq = imx6ul_ccm_get_per_clk(s);
521         break;
522     case CLK_32k:
523         freq = CKIL_FREQ;
524         break;
525     case CLK_HIGH:
526         freq = CKIH_FREQ;
527         break;
528     case CLK_HIGH_DIV:
529         freq = CKIH_FREQ / 8;
530         break;
531     default:
532         qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: unsupported clock %d\n",
533                       TYPE_IMX6UL_CCM, __func__, clock);
534         break;
535     }
536 
537     trace_ccm_clock_freq(clock, freq);
538 
539     return freq;
540 }
541 
542 static void imx6ul_ccm_reset(DeviceState *dev)
543 {
544     IMX6ULCCMState *s = IMX6UL_CCM(dev);
545 
546     trace_ccm_entry();
547 
548     s->ccm[CCM_CCR] = 0x0401167F;
549     s->ccm[CCM_CCDR] = 0x00000000;
550     s->ccm[CCM_CSR] = 0x00000010;
551     s->ccm[CCM_CCSR] = 0x00000100;
552     s->ccm[CCM_CACRR] = 0x00000000;
553     s->ccm[CCM_CBCDR] = 0x00018D00;
554     s->ccm[CCM_CBCMR] = 0x24860324;
555     s->ccm[CCM_CSCMR1] = 0x04900080;
556     s->ccm[CCM_CSCMR2] = 0x03192F06;
557     s->ccm[CCM_CSCDR1] = 0x00490B00;
558     s->ccm[CCM_CS1CDR] = 0x0EC102C1;
559     s->ccm[CCM_CS2CDR] = 0x000336C1;
560     s->ccm[CCM_CDCDR] = 0x33F71F92;
561     s->ccm[CCM_CHSCCDR] = 0x000248A4;
562     s->ccm[CCM_CSCDR2] = 0x00029B48;
563     s->ccm[CCM_CSCDR3] = 0x00014841;
564     s->ccm[CCM_CDHIPR] = 0x00000000;
565     s->ccm[CCM_CTOR] = 0x00000000;
566     s->ccm[CCM_CLPCR] = 0x00000079;
567     s->ccm[CCM_CISR] = 0x00000000;
568     s->ccm[CCM_CIMR] = 0xFFFFFFFF;
569     s->ccm[CCM_CCOSR] = 0x000A0001;
570     s->ccm[CCM_CGPR] = 0x0000FE62;
571     s->ccm[CCM_CCGR0] = 0xFFFFFFFF;
572     s->ccm[CCM_CCGR1] = 0xFFFFFFFF;
573     s->ccm[CCM_CCGR2] = 0xFC3FFFFF;
574     s->ccm[CCM_CCGR3] = 0xFFFFFFFF;
575     s->ccm[CCM_CCGR4] = 0xFFFFFFFF;
576     s->ccm[CCM_CCGR5] = 0xFFFFFFFF;
577     s->ccm[CCM_CCGR6] = 0xFFFFFFFF;
578     s->ccm[CCM_CMEOR] = 0xFFFFFFFF;
579 
580     s->analog[CCM_ANALOG_PLL_ARM] = 0x00013063;
581     s->analog[CCM_ANALOG_PLL_USB1] = 0x00012000;
582     s->analog[CCM_ANALOG_PLL_USB2] = 0x00012000;
583     s->analog[CCM_ANALOG_PLL_SYS] = 0x00013001;
584     s->analog[CCM_ANALOG_PLL_SYS_SS] = 0x00000000;
585     s->analog[CCM_ANALOG_PLL_SYS_NUM] = 0x00000000;
586     s->analog[CCM_ANALOG_PLL_SYS_DENOM] = 0x00000012;
587     s->analog[CCM_ANALOG_PLL_AUDIO] = 0x00011006;
588     s->analog[CCM_ANALOG_PLL_AUDIO_NUM] = 0x05F5E100;
589     s->analog[CCM_ANALOG_PLL_AUDIO_DENOM] = 0x2964619C;
590     s->analog[CCM_ANALOG_PLL_VIDEO] = 0x0001100C;
591     s->analog[CCM_ANALOG_PLL_VIDEO_NUM] = 0x05F5E100;
592     s->analog[CCM_ANALOG_PLL_VIDEO_DENOM] = 0x10A24447;
593     s->analog[CCM_ANALOG_PLL_ENET] = 0x00011001;
594     s->analog[CCM_ANALOG_PFD_480] = 0x1311100C;
595     s->analog[CCM_ANALOG_PFD_528] = 0x1018101B;
596 
597     s->analog[PMU_REG_1P1] = 0x00001073;
598     s->analog[PMU_REG_3P0] = 0x00000F74;
599     s->analog[PMU_REG_2P5] = 0x00001073;
600     s->analog[PMU_REG_CORE] = 0x00482012;
601     s->analog[PMU_MISC0] = 0x04000000;
602     s->analog[PMU_MISC1] = 0x00000000;
603     s->analog[PMU_MISC2] = 0x00272727;
604     s->analog[PMU_LOWPWR_CTRL] = 0x00004009;
605 
606     s->analog[USB_ANALOG_USB1_VBUS_DETECT] = 0x01000004;
607     s->analog[USB_ANALOG_USB1_CHRG_DETECT] = 0x00000000;
608     s->analog[USB_ANALOG_USB1_VBUS_DETECT_STAT] = 0x00000000;
609     s->analog[USB_ANALOG_USB1_CHRG_DETECT_STAT] = 0x00000000;
610     s->analog[USB_ANALOG_USB1_MISC] = 0x00000002;
611     s->analog[USB_ANALOG_USB2_VBUS_DETECT] = 0x01000004;
612     s->analog[USB_ANALOG_USB2_CHRG_DETECT] = 0x00000000;
613     s->analog[USB_ANALOG_USB2_MISC] = 0x00000002;
614     s->analog[USB_ANALOG_DIGPROG] = 0x00640000;
615 
616     /* all PLLs need to be locked */
617     s->analog[CCM_ANALOG_PLL_ARM]   |= CCM_ANALOG_PLL_LOCK;
618     s->analog[CCM_ANALOG_PLL_USB1]  |= CCM_ANALOG_PLL_LOCK;
619     s->analog[CCM_ANALOG_PLL_USB2]  |= CCM_ANALOG_PLL_LOCK;
620     s->analog[CCM_ANALOG_PLL_SYS]   |= CCM_ANALOG_PLL_LOCK;
621     s->analog[CCM_ANALOG_PLL_AUDIO] |= CCM_ANALOG_PLL_LOCK;
622     s->analog[CCM_ANALOG_PLL_VIDEO] |= CCM_ANALOG_PLL_LOCK;
623     s->analog[CCM_ANALOG_PLL_ENET]  |= CCM_ANALOG_PLL_LOCK;
624 
625     s->analog[TEMPMON_TEMPSENSE0] = 0x00000001;
626     s->analog[TEMPMON_TEMPSENSE1] = 0x00000001;
627     s->analog[TEMPMON_TEMPSENSE2] = 0x00000000;
628 }
629 
630 static uint64_t imx6ul_ccm_read(void *opaque, hwaddr offset, unsigned size)
631 {
632     uint32_t value = 0;
633     uint32_t index = offset >> 2;
634     IMX6ULCCMState *s = (IMX6ULCCMState *)opaque;
635 
636     assert(index < CCM_MAX);
637 
638     value = s->ccm[index];
639 
640     trace_ccm_read_reg(imx6ul_ccm_reg_name(index), (uint32_t)value);
641 
642     return (uint64_t)value;
643 }
644 
645 static void imx6ul_ccm_write(void *opaque, hwaddr offset, uint64_t value,
646                            unsigned size)
647 {
648     uint32_t index = offset >> 2;
649     IMX6ULCCMState *s = (IMX6ULCCMState *)opaque;
650 
651     assert(index < CCM_MAX);
652 
653     trace_ccm_write_reg(imx6ul_ccm_reg_name(index), (uint32_t)value);
654 
655     s->ccm[index] = (s->ccm[index] & ccm_mask[index]) |
656                            ((uint32_t)value & ~ccm_mask[index]);
657 }
658 
659 static uint64_t imx6ul_analog_read(void *opaque, hwaddr offset, unsigned size)
660 {
661     uint32_t value;
662     uint32_t index = offset >> 2;
663     IMX6ULCCMState *s = (IMX6ULCCMState *)opaque;
664 
665     assert(index < CCM_ANALOG_MAX);
666 
667     switch (index) {
668     case CCM_ANALOG_PLL_ARM_SET:
669     case CCM_ANALOG_PLL_USB1_SET:
670     case CCM_ANALOG_PLL_USB2_SET:
671     case CCM_ANALOG_PLL_SYS_SET:
672     case CCM_ANALOG_PLL_AUDIO_SET:
673     case CCM_ANALOG_PLL_VIDEO_SET:
674     case CCM_ANALOG_PLL_ENET_SET:
675     case CCM_ANALOG_PFD_480_SET:
676     case CCM_ANALOG_PFD_528_SET:
677     case CCM_ANALOG_MISC0_SET:
678     case PMU_MISC1_SET:
679     case CCM_ANALOG_MISC2_SET:
680     case USB_ANALOG_USB1_VBUS_DETECT_SET:
681     case USB_ANALOG_USB1_CHRG_DETECT_SET:
682     case USB_ANALOG_USB1_MISC_SET:
683     case USB_ANALOG_USB2_VBUS_DETECT_SET:
684     case USB_ANALOG_USB2_CHRG_DETECT_SET:
685     case USB_ANALOG_USB2_MISC_SET:
686     case TEMPMON_TEMPSENSE0_SET:
687     case TEMPMON_TEMPSENSE1_SET:
688     case TEMPMON_TEMPSENSE2_SET:
689         /*
690          * All REG_NAME_SET register access are in fact targeting
691          * the REG_NAME register.
692          */
693         value = s->analog[index - 1];
694         break;
695     case CCM_ANALOG_PLL_ARM_CLR:
696     case CCM_ANALOG_PLL_USB1_CLR:
697     case CCM_ANALOG_PLL_USB2_CLR:
698     case CCM_ANALOG_PLL_SYS_CLR:
699     case CCM_ANALOG_PLL_AUDIO_CLR:
700     case CCM_ANALOG_PLL_VIDEO_CLR:
701     case CCM_ANALOG_PLL_ENET_CLR:
702     case CCM_ANALOG_PFD_480_CLR:
703     case CCM_ANALOG_PFD_528_CLR:
704     case CCM_ANALOG_MISC0_CLR:
705     case PMU_MISC1_CLR:
706     case CCM_ANALOG_MISC2_CLR:
707     case USB_ANALOG_USB1_VBUS_DETECT_CLR:
708     case USB_ANALOG_USB1_CHRG_DETECT_CLR:
709     case USB_ANALOG_USB1_MISC_CLR:
710     case USB_ANALOG_USB2_VBUS_DETECT_CLR:
711     case USB_ANALOG_USB2_CHRG_DETECT_CLR:
712     case USB_ANALOG_USB2_MISC_CLR:
713     case TEMPMON_TEMPSENSE0_CLR:
714     case TEMPMON_TEMPSENSE1_CLR:
715     case TEMPMON_TEMPSENSE2_CLR:
716         /*
717          * All REG_NAME_CLR register access are in fact targeting
718          * the REG_NAME register.
719          */
720         value = s->analog[index - 2];
721         break;
722     case CCM_ANALOG_PLL_ARM_TOG:
723     case CCM_ANALOG_PLL_USB1_TOG:
724     case CCM_ANALOG_PLL_USB2_TOG:
725     case CCM_ANALOG_PLL_SYS_TOG:
726     case CCM_ANALOG_PLL_AUDIO_TOG:
727     case CCM_ANALOG_PLL_VIDEO_TOG:
728     case CCM_ANALOG_PLL_ENET_TOG:
729     case CCM_ANALOG_PFD_480_TOG:
730     case CCM_ANALOG_PFD_528_TOG:
731     case CCM_ANALOG_MISC0_TOG:
732     case PMU_MISC1_TOG:
733     case CCM_ANALOG_MISC2_TOG:
734     case USB_ANALOG_USB1_VBUS_DETECT_TOG:
735     case USB_ANALOG_USB1_CHRG_DETECT_TOG:
736     case USB_ANALOG_USB1_MISC_TOG:
737     case USB_ANALOG_USB2_VBUS_DETECT_TOG:
738     case USB_ANALOG_USB2_CHRG_DETECT_TOG:
739     case USB_ANALOG_USB2_MISC_TOG:
740     case TEMPMON_TEMPSENSE0_TOG:
741     case TEMPMON_TEMPSENSE1_TOG:
742     case TEMPMON_TEMPSENSE2_TOG:
743         /*
744          * All REG_NAME_TOG register access are in fact targeting
745          * the REG_NAME register.
746          */
747         value = s->analog[index - 3];
748         break;
749     default:
750         value = s->analog[index];
751         break;
752     }
753 
754     trace_ccm_read_reg(imx6ul_analog_reg_name(index), (uint32_t)value);
755 
756     return (uint64_t)value;
757 }
758 
759 static void imx6ul_analog_write(void *opaque, hwaddr offset, uint64_t value,
760                               unsigned size)
761 {
762     uint32_t index = offset >> 2;
763     IMX6ULCCMState *s = (IMX6ULCCMState *)opaque;
764 
765     assert(index < CCM_ANALOG_MAX);
766 
767     trace_ccm_write_reg(imx6ul_analog_reg_name(index), (uint32_t)value);
768 
769     switch (index) {
770     case CCM_ANALOG_PLL_ARM_SET:
771     case CCM_ANALOG_PLL_USB1_SET:
772     case CCM_ANALOG_PLL_USB2_SET:
773     case CCM_ANALOG_PLL_SYS_SET:
774     case CCM_ANALOG_PLL_AUDIO_SET:
775     case CCM_ANALOG_PLL_VIDEO_SET:
776     case CCM_ANALOG_PLL_ENET_SET:
777     case CCM_ANALOG_PFD_480_SET:
778     case CCM_ANALOG_PFD_528_SET:
779     case CCM_ANALOG_MISC0_SET:
780     case PMU_MISC1_SET:
781     case CCM_ANALOG_MISC2_SET:
782     case USB_ANALOG_USB1_VBUS_DETECT_SET:
783     case USB_ANALOG_USB1_CHRG_DETECT_SET:
784     case USB_ANALOG_USB1_MISC_SET:
785     case USB_ANALOG_USB2_VBUS_DETECT_SET:
786     case USB_ANALOG_USB2_CHRG_DETECT_SET:
787     case USB_ANALOG_USB2_MISC_SET:
788         /*
789          * All REG_NAME_SET register access are in fact targeting
790          * the REG_NAME register. So we change the value of the
791          * REG_NAME register, setting bits passed in the value.
792          */
793         s->analog[index - 1] |= (value & ~analog_mask[index - 1]);
794         break;
795     case CCM_ANALOG_PLL_ARM_CLR:
796     case CCM_ANALOG_PLL_USB1_CLR:
797     case CCM_ANALOG_PLL_USB2_CLR:
798     case CCM_ANALOG_PLL_SYS_CLR:
799     case CCM_ANALOG_PLL_AUDIO_CLR:
800     case CCM_ANALOG_PLL_VIDEO_CLR:
801     case CCM_ANALOG_PLL_ENET_CLR:
802     case CCM_ANALOG_PFD_480_CLR:
803     case CCM_ANALOG_PFD_528_CLR:
804     case CCM_ANALOG_MISC0_CLR:
805     case PMU_MISC1_CLR:
806     case CCM_ANALOG_MISC2_CLR:
807     case USB_ANALOG_USB1_VBUS_DETECT_CLR:
808     case USB_ANALOG_USB1_CHRG_DETECT_CLR:
809     case USB_ANALOG_USB1_MISC_CLR:
810     case USB_ANALOG_USB2_VBUS_DETECT_CLR:
811     case USB_ANALOG_USB2_CHRG_DETECT_CLR:
812     case USB_ANALOG_USB2_MISC_CLR:
813         /*
814          * All REG_NAME_CLR register access are in fact targeting
815          * the REG_NAME register. So we change the value of the
816          * REG_NAME register, unsetting bits passed in the value.
817          */
818         s->analog[index - 2] &= ~(value & ~analog_mask[index - 2]);
819         break;
820     case CCM_ANALOG_PLL_ARM_TOG:
821     case CCM_ANALOG_PLL_USB1_TOG:
822     case CCM_ANALOG_PLL_USB2_TOG:
823     case CCM_ANALOG_PLL_SYS_TOG:
824     case CCM_ANALOG_PLL_AUDIO_TOG:
825     case CCM_ANALOG_PLL_VIDEO_TOG:
826     case CCM_ANALOG_PLL_ENET_TOG:
827     case CCM_ANALOG_PFD_480_TOG:
828     case CCM_ANALOG_PFD_528_TOG:
829     case CCM_ANALOG_MISC0_TOG:
830     case PMU_MISC1_TOG:
831     case CCM_ANALOG_MISC2_TOG:
832     case USB_ANALOG_USB1_VBUS_DETECT_TOG:
833     case USB_ANALOG_USB1_CHRG_DETECT_TOG:
834     case USB_ANALOG_USB1_MISC_TOG:
835     case USB_ANALOG_USB2_VBUS_DETECT_TOG:
836     case USB_ANALOG_USB2_CHRG_DETECT_TOG:
837     case USB_ANALOG_USB2_MISC_TOG:
838         /*
839          * All REG_NAME_TOG register access are in fact targeting
840          * the REG_NAME register. So we change the value of the
841          * REG_NAME register, toggling bits passed in the value.
842          */
843         s->analog[index - 3] ^= (value & ~analog_mask[index - 3]);
844         break;
845     default:
846         s->analog[index] = (s->analog[index] & analog_mask[index]) |
847                            (value & ~analog_mask[index]);
848         break;
849     }
850 }
851 
852 static const struct MemoryRegionOps imx6ul_ccm_ops = {
853     .read = imx6ul_ccm_read,
854     .write = imx6ul_ccm_write,
855     .endianness = DEVICE_NATIVE_ENDIAN,
856     .valid = {
857         /*
858          * Our device would not work correctly if the guest was doing
859          * unaligned access. This might not be a limitation on the real
860          * device but in practice there is no reason for a guest to access
861          * this device unaligned.
862          */
863         .min_access_size = 4,
864         .max_access_size = 4,
865         .unaligned = false,
866     },
867 };
868 
869 static const struct MemoryRegionOps imx6ul_analog_ops = {
870     .read = imx6ul_analog_read,
871     .write = imx6ul_analog_write,
872     .endianness = DEVICE_NATIVE_ENDIAN,
873     .valid = {
874         /*
875          * Our device would not work correctly if the guest was doing
876          * unaligned access. This might not be a limitation on the real
877          * device but in practice there is no reason for a guest to access
878          * this device unaligned.
879          */
880         .min_access_size = 4,
881         .max_access_size = 4,
882         .unaligned = false,
883     },
884 };
885 
886 static void imx6ul_ccm_init(Object *obj)
887 {
888     DeviceState *dev = DEVICE(obj);
889     SysBusDevice *sd = SYS_BUS_DEVICE(obj);
890     IMX6ULCCMState *s = IMX6UL_CCM(obj);
891 
892     /* initialize a container for the all memory range */
893     memory_region_init(&s->container, OBJECT(dev), TYPE_IMX6UL_CCM, 0x8000);
894 
895     /* We initialize an IO memory region for the CCM part */
896     memory_region_init_io(&s->ioccm, OBJECT(dev), &imx6ul_ccm_ops, s,
897                           TYPE_IMX6UL_CCM ".ccm", CCM_MAX * sizeof(uint32_t));
898 
899     /* Add the CCM as a subregion at offset 0 */
900     memory_region_add_subregion(&s->container, 0, &s->ioccm);
901 
902     /* We initialize an IO memory region for the ANALOG part */
903     memory_region_init_io(&s->ioanalog, OBJECT(dev), &imx6ul_analog_ops, s,
904                           TYPE_IMX6UL_CCM ".analog",
905                           CCM_ANALOG_MAX * sizeof(uint32_t));
906 
907     /* Add the ANALOG as a subregion at offset 0x4000 */
908     memory_region_add_subregion(&s->container, 0x4000, &s->ioanalog);
909 
910     sysbus_init_mmio(sd, &s->container);
911 }
912 
913 static void imx6ul_ccm_class_init(ObjectClass *klass, void *data)
914 {
915     DeviceClass *dc = DEVICE_CLASS(klass);
916     IMXCCMClass *ccm = IMX_CCM_CLASS(klass);
917 
918     dc->reset = imx6ul_ccm_reset;
919     dc->vmsd = &vmstate_imx6ul_ccm;
920     dc->desc = "i.MX6UL Clock Control Module";
921 
922     ccm->get_clock_frequency = imx6ul_ccm_get_clock_frequency;
923 }
924 
925 static const TypeInfo imx6ul_ccm_info = {
926     .name          = TYPE_IMX6UL_CCM,
927     .parent        = TYPE_IMX_CCM,
928     .instance_size = sizeof(IMX6ULCCMState),
929     .instance_init = imx6ul_ccm_init,
930     .class_init    = imx6ul_ccm_class_init,
931 };
932 
933 static void imx6ul_ccm_register_types(void)
934 {
935     type_register_static(&imx6ul_ccm_info);
936 }
937 
938 type_init(imx6ul_ccm_register_types)
939