xref: /openbmc/qemu/hw/misc/imx6ul_ccm.c (revision 1de81b42)
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 = (const 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     default:
526         qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: unsupported clock %d\n",
527                       TYPE_IMX6UL_CCM, __func__, clock);
528         break;
529     }
530 
531     trace_ccm_clock_freq(clock, freq);
532 
533     return freq;
534 }
535 
536 static void imx6ul_ccm_reset(DeviceState *dev)
537 {
538     IMX6ULCCMState *s = IMX6UL_CCM(dev);
539 
540     trace_ccm_entry();
541 
542     s->ccm[CCM_CCR] = 0x0401167F;
543     s->ccm[CCM_CCDR] = 0x00000000;
544     s->ccm[CCM_CSR] = 0x00000010;
545     s->ccm[CCM_CCSR] = 0x00000100;
546     s->ccm[CCM_CACRR] = 0x00000000;
547     s->ccm[CCM_CBCDR] = 0x00018D00;
548     s->ccm[CCM_CBCMR] = 0x24860324;
549     s->ccm[CCM_CSCMR1] = 0x04900080;
550     s->ccm[CCM_CSCMR2] = 0x03192F06;
551     s->ccm[CCM_CSCDR1] = 0x00490B00;
552     s->ccm[CCM_CS1CDR] = 0x0EC102C1;
553     s->ccm[CCM_CS2CDR] = 0x000336C1;
554     s->ccm[CCM_CDCDR] = 0x33F71F92;
555     s->ccm[CCM_CHSCCDR] = 0x000248A4;
556     s->ccm[CCM_CSCDR2] = 0x00029B48;
557     s->ccm[CCM_CSCDR3] = 0x00014841;
558     s->ccm[CCM_CDHIPR] = 0x00000000;
559     s->ccm[CCM_CTOR] = 0x00000000;
560     s->ccm[CCM_CLPCR] = 0x00000079;
561     s->ccm[CCM_CISR] = 0x00000000;
562     s->ccm[CCM_CIMR] = 0xFFFFFFFF;
563     s->ccm[CCM_CCOSR] = 0x000A0001;
564     s->ccm[CCM_CGPR] = 0x0000FE62;
565     s->ccm[CCM_CCGR0] = 0xFFFFFFFF;
566     s->ccm[CCM_CCGR1] = 0xFFFFFFFF;
567     s->ccm[CCM_CCGR2] = 0xFC3FFFFF;
568     s->ccm[CCM_CCGR3] = 0xFFFFFFFF;
569     s->ccm[CCM_CCGR4] = 0xFFFFFFFF;
570     s->ccm[CCM_CCGR5] = 0xFFFFFFFF;
571     s->ccm[CCM_CCGR6] = 0xFFFFFFFF;
572     s->ccm[CCM_CMEOR] = 0xFFFFFFFF;
573 
574     s->analog[CCM_ANALOG_PLL_ARM] = 0x00013063;
575     s->analog[CCM_ANALOG_PLL_USB1] = 0x00012000;
576     s->analog[CCM_ANALOG_PLL_USB2] = 0x00012000;
577     s->analog[CCM_ANALOG_PLL_SYS] = 0x00013001;
578     s->analog[CCM_ANALOG_PLL_SYS_SS] = 0x00000000;
579     s->analog[CCM_ANALOG_PLL_SYS_NUM] = 0x00000000;
580     s->analog[CCM_ANALOG_PLL_SYS_DENOM] = 0x00000012;
581     s->analog[CCM_ANALOG_PLL_AUDIO] = 0x00011006;
582     s->analog[CCM_ANALOG_PLL_AUDIO_NUM] = 0x05F5E100;
583     s->analog[CCM_ANALOG_PLL_AUDIO_DENOM] = 0x2964619C;
584     s->analog[CCM_ANALOG_PLL_VIDEO] = 0x0001100C;
585     s->analog[CCM_ANALOG_PLL_VIDEO_NUM] = 0x05F5E100;
586     s->analog[CCM_ANALOG_PLL_VIDEO_DENOM] = 0x10A24447;
587     s->analog[CCM_ANALOG_PLL_ENET] = 0x00011001;
588     s->analog[CCM_ANALOG_PFD_480] = 0x1311100C;
589     s->analog[CCM_ANALOG_PFD_528] = 0x1018101B;
590 
591     s->analog[PMU_REG_1P1] = 0x00001073;
592     s->analog[PMU_REG_3P0] = 0x00000F74;
593     s->analog[PMU_REG_2P5] = 0x00001073;
594     s->analog[PMU_REG_CORE] = 0x00482012;
595     s->analog[PMU_MISC0] = 0x04000000;
596     s->analog[PMU_MISC1] = 0x00000000;
597     s->analog[PMU_MISC2] = 0x00272727;
598     s->analog[PMU_LOWPWR_CTRL] = 0x00004009;
599 
600     s->analog[USB_ANALOG_USB1_VBUS_DETECT] = 0x01000004;
601     s->analog[USB_ANALOG_USB1_CHRG_DETECT] = 0x00000000;
602     s->analog[USB_ANALOG_USB1_VBUS_DETECT_STAT] = 0x00000000;
603     s->analog[USB_ANALOG_USB1_CHRG_DETECT_STAT] = 0x00000000;
604     s->analog[USB_ANALOG_USB1_MISC] = 0x00000002;
605     s->analog[USB_ANALOG_USB2_VBUS_DETECT] = 0x01000004;
606     s->analog[USB_ANALOG_USB2_CHRG_DETECT] = 0x00000000;
607     s->analog[USB_ANALOG_USB2_MISC] = 0x00000002;
608     s->analog[USB_ANALOG_DIGPROG] = 0x00640000;
609 
610     /* all PLLs need to be locked */
611     s->analog[CCM_ANALOG_PLL_ARM]   |= CCM_ANALOG_PLL_LOCK;
612     s->analog[CCM_ANALOG_PLL_USB1]  |= CCM_ANALOG_PLL_LOCK;
613     s->analog[CCM_ANALOG_PLL_USB2]  |= CCM_ANALOG_PLL_LOCK;
614     s->analog[CCM_ANALOG_PLL_SYS]   |= CCM_ANALOG_PLL_LOCK;
615     s->analog[CCM_ANALOG_PLL_AUDIO] |= CCM_ANALOG_PLL_LOCK;
616     s->analog[CCM_ANALOG_PLL_VIDEO] |= CCM_ANALOG_PLL_LOCK;
617     s->analog[CCM_ANALOG_PLL_ENET]  |= CCM_ANALOG_PLL_LOCK;
618 
619     s->analog[TEMPMON_TEMPSENSE0] = 0x00000001;
620     s->analog[TEMPMON_TEMPSENSE1] = 0x00000001;
621     s->analog[TEMPMON_TEMPSENSE2] = 0x00000000;
622 }
623 
624 static uint64_t imx6ul_ccm_read(void *opaque, hwaddr offset, unsigned size)
625 {
626     uint32_t value = 0;
627     uint32_t index = offset >> 2;
628     IMX6ULCCMState *s = (IMX6ULCCMState *)opaque;
629 
630     assert(index < CCM_MAX);
631 
632     value = s->ccm[index];
633 
634     trace_ccm_read_reg(imx6ul_ccm_reg_name(index), (uint32_t)value);
635 
636     return (uint64_t)value;
637 }
638 
639 static void imx6ul_ccm_write(void *opaque, hwaddr offset, uint64_t value,
640                            unsigned size)
641 {
642     uint32_t index = offset >> 2;
643     IMX6ULCCMState *s = (IMX6ULCCMState *)opaque;
644 
645     assert(index < CCM_MAX);
646 
647     trace_ccm_write_reg(imx6ul_ccm_reg_name(index), (uint32_t)value);
648 
649     s->ccm[index] = (s->ccm[index] & ccm_mask[index]) |
650                            ((uint32_t)value & ~ccm_mask[index]);
651 }
652 
653 static uint64_t imx6ul_analog_read(void *opaque, hwaddr offset, unsigned size)
654 {
655     uint32_t value;
656     uint32_t index = offset >> 2;
657     IMX6ULCCMState *s = (IMX6ULCCMState *)opaque;
658 
659     assert(index < CCM_ANALOG_MAX);
660 
661     switch (index) {
662     case CCM_ANALOG_PLL_ARM_SET:
663     case CCM_ANALOG_PLL_USB1_SET:
664     case CCM_ANALOG_PLL_USB2_SET:
665     case CCM_ANALOG_PLL_SYS_SET:
666     case CCM_ANALOG_PLL_AUDIO_SET:
667     case CCM_ANALOG_PLL_VIDEO_SET:
668     case CCM_ANALOG_PLL_ENET_SET:
669     case CCM_ANALOG_PFD_480_SET:
670     case CCM_ANALOG_PFD_528_SET:
671     case CCM_ANALOG_MISC0_SET:
672     case PMU_MISC1_SET:
673     case CCM_ANALOG_MISC2_SET:
674     case USB_ANALOG_USB1_VBUS_DETECT_SET:
675     case USB_ANALOG_USB1_CHRG_DETECT_SET:
676     case USB_ANALOG_USB1_MISC_SET:
677     case USB_ANALOG_USB2_VBUS_DETECT_SET:
678     case USB_ANALOG_USB2_CHRG_DETECT_SET:
679     case USB_ANALOG_USB2_MISC_SET:
680     case TEMPMON_TEMPSENSE0_SET:
681     case TEMPMON_TEMPSENSE1_SET:
682     case TEMPMON_TEMPSENSE2_SET:
683         /*
684          * All REG_NAME_SET register access are in fact targeting
685          * the REG_NAME register.
686          */
687         value = s->analog[index - 1];
688         break;
689     case CCM_ANALOG_PLL_ARM_CLR:
690     case CCM_ANALOG_PLL_USB1_CLR:
691     case CCM_ANALOG_PLL_USB2_CLR:
692     case CCM_ANALOG_PLL_SYS_CLR:
693     case CCM_ANALOG_PLL_AUDIO_CLR:
694     case CCM_ANALOG_PLL_VIDEO_CLR:
695     case CCM_ANALOG_PLL_ENET_CLR:
696     case CCM_ANALOG_PFD_480_CLR:
697     case CCM_ANALOG_PFD_528_CLR:
698     case CCM_ANALOG_MISC0_CLR:
699     case PMU_MISC1_CLR:
700     case CCM_ANALOG_MISC2_CLR:
701     case USB_ANALOG_USB1_VBUS_DETECT_CLR:
702     case USB_ANALOG_USB1_CHRG_DETECT_CLR:
703     case USB_ANALOG_USB1_MISC_CLR:
704     case USB_ANALOG_USB2_VBUS_DETECT_CLR:
705     case USB_ANALOG_USB2_CHRG_DETECT_CLR:
706     case USB_ANALOG_USB2_MISC_CLR:
707     case TEMPMON_TEMPSENSE0_CLR:
708     case TEMPMON_TEMPSENSE1_CLR:
709     case TEMPMON_TEMPSENSE2_CLR:
710         /*
711          * All REG_NAME_CLR register access are in fact targeting
712          * the REG_NAME register.
713          */
714         value = s->analog[index - 2];
715         break;
716     case CCM_ANALOG_PLL_ARM_TOG:
717     case CCM_ANALOG_PLL_USB1_TOG:
718     case CCM_ANALOG_PLL_USB2_TOG:
719     case CCM_ANALOG_PLL_SYS_TOG:
720     case CCM_ANALOG_PLL_AUDIO_TOG:
721     case CCM_ANALOG_PLL_VIDEO_TOG:
722     case CCM_ANALOG_PLL_ENET_TOG:
723     case CCM_ANALOG_PFD_480_TOG:
724     case CCM_ANALOG_PFD_528_TOG:
725     case CCM_ANALOG_MISC0_TOG:
726     case PMU_MISC1_TOG:
727     case CCM_ANALOG_MISC2_TOG:
728     case USB_ANALOG_USB1_VBUS_DETECT_TOG:
729     case USB_ANALOG_USB1_CHRG_DETECT_TOG:
730     case USB_ANALOG_USB1_MISC_TOG:
731     case USB_ANALOG_USB2_VBUS_DETECT_TOG:
732     case USB_ANALOG_USB2_CHRG_DETECT_TOG:
733     case USB_ANALOG_USB2_MISC_TOG:
734     case TEMPMON_TEMPSENSE0_TOG:
735     case TEMPMON_TEMPSENSE1_TOG:
736     case TEMPMON_TEMPSENSE2_TOG:
737         /*
738          * All REG_NAME_TOG register access are in fact targeting
739          * the REG_NAME register.
740          */
741         value = s->analog[index - 3];
742         break;
743     default:
744         value = s->analog[index];
745         break;
746     }
747 
748     trace_ccm_read_reg(imx6ul_analog_reg_name(index), (uint32_t)value);
749 
750     return (uint64_t)value;
751 }
752 
753 static void imx6ul_analog_write(void *opaque, hwaddr offset, uint64_t value,
754                               unsigned size)
755 {
756     uint32_t index = offset >> 2;
757     IMX6ULCCMState *s = (IMX6ULCCMState *)opaque;
758 
759     assert(index < CCM_ANALOG_MAX);
760 
761     trace_ccm_write_reg(imx6ul_analog_reg_name(index), (uint32_t)value);
762 
763     switch (index) {
764     case CCM_ANALOG_PLL_ARM_SET:
765     case CCM_ANALOG_PLL_USB1_SET:
766     case CCM_ANALOG_PLL_USB2_SET:
767     case CCM_ANALOG_PLL_SYS_SET:
768     case CCM_ANALOG_PLL_AUDIO_SET:
769     case CCM_ANALOG_PLL_VIDEO_SET:
770     case CCM_ANALOG_PLL_ENET_SET:
771     case CCM_ANALOG_PFD_480_SET:
772     case CCM_ANALOG_PFD_528_SET:
773     case CCM_ANALOG_MISC0_SET:
774     case PMU_MISC1_SET:
775     case CCM_ANALOG_MISC2_SET:
776     case USB_ANALOG_USB1_VBUS_DETECT_SET:
777     case USB_ANALOG_USB1_CHRG_DETECT_SET:
778     case USB_ANALOG_USB1_MISC_SET:
779     case USB_ANALOG_USB2_VBUS_DETECT_SET:
780     case USB_ANALOG_USB2_CHRG_DETECT_SET:
781     case USB_ANALOG_USB2_MISC_SET:
782         /*
783          * All REG_NAME_SET register access are in fact targeting
784          * the REG_NAME register. So we change the value of the
785          * REG_NAME register, setting bits passed in the value.
786          */
787         s->analog[index - 1] |= (value & ~analog_mask[index - 1]);
788         break;
789     case CCM_ANALOG_PLL_ARM_CLR:
790     case CCM_ANALOG_PLL_USB1_CLR:
791     case CCM_ANALOG_PLL_USB2_CLR:
792     case CCM_ANALOG_PLL_SYS_CLR:
793     case CCM_ANALOG_PLL_AUDIO_CLR:
794     case CCM_ANALOG_PLL_VIDEO_CLR:
795     case CCM_ANALOG_PLL_ENET_CLR:
796     case CCM_ANALOG_PFD_480_CLR:
797     case CCM_ANALOG_PFD_528_CLR:
798     case CCM_ANALOG_MISC0_CLR:
799     case PMU_MISC1_CLR:
800     case CCM_ANALOG_MISC2_CLR:
801     case USB_ANALOG_USB1_VBUS_DETECT_CLR:
802     case USB_ANALOG_USB1_CHRG_DETECT_CLR:
803     case USB_ANALOG_USB1_MISC_CLR:
804     case USB_ANALOG_USB2_VBUS_DETECT_CLR:
805     case USB_ANALOG_USB2_CHRG_DETECT_CLR:
806     case USB_ANALOG_USB2_MISC_CLR:
807         /*
808          * All REG_NAME_CLR register access are in fact targeting
809          * the REG_NAME register. So we change the value of the
810          * REG_NAME register, unsetting bits passed in the value.
811          */
812         s->analog[index - 2] &= ~(value & ~analog_mask[index - 2]);
813         break;
814     case CCM_ANALOG_PLL_ARM_TOG:
815     case CCM_ANALOG_PLL_USB1_TOG:
816     case CCM_ANALOG_PLL_USB2_TOG:
817     case CCM_ANALOG_PLL_SYS_TOG:
818     case CCM_ANALOG_PLL_AUDIO_TOG:
819     case CCM_ANALOG_PLL_VIDEO_TOG:
820     case CCM_ANALOG_PLL_ENET_TOG:
821     case CCM_ANALOG_PFD_480_TOG:
822     case CCM_ANALOG_PFD_528_TOG:
823     case CCM_ANALOG_MISC0_TOG:
824     case PMU_MISC1_TOG:
825     case CCM_ANALOG_MISC2_TOG:
826     case USB_ANALOG_USB1_VBUS_DETECT_TOG:
827     case USB_ANALOG_USB1_CHRG_DETECT_TOG:
828     case USB_ANALOG_USB1_MISC_TOG:
829     case USB_ANALOG_USB2_VBUS_DETECT_TOG:
830     case USB_ANALOG_USB2_CHRG_DETECT_TOG:
831     case USB_ANALOG_USB2_MISC_TOG:
832         /*
833          * All REG_NAME_TOG register access are in fact targeting
834          * the REG_NAME register. So we change the value of the
835          * REG_NAME register, toggling bits passed in the value.
836          */
837         s->analog[index - 3] ^= (value & ~analog_mask[index - 3]);
838         break;
839     default:
840         s->analog[index] = (s->analog[index] & analog_mask[index]) |
841                            (value & ~analog_mask[index]);
842         break;
843     }
844 }
845 
846 static const struct MemoryRegionOps imx6ul_ccm_ops = {
847     .read = imx6ul_ccm_read,
848     .write = imx6ul_ccm_write,
849     .endianness = DEVICE_NATIVE_ENDIAN,
850     .valid = {
851         /*
852          * Our device would not work correctly if the guest was doing
853          * unaligned access. This might not be a limitation on the real
854          * device but in practice there is no reason for a guest to access
855          * this device unaligned.
856          */
857         .min_access_size = 4,
858         .max_access_size = 4,
859         .unaligned = false,
860     },
861 };
862 
863 static const struct MemoryRegionOps imx6ul_analog_ops = {
864     .read = imx6ul_analog_read,
865     .write = imx6ul_analog_write,
866     .endianness = DEVICE_NATIVE_ENDIAN,
867     .valid = {
868         /*
869          * Our device would not work correctly if the guest was doing
870          * unaligned access. This might not be a limitation on the real
871          * device but in practice there is no reason for a guest to access
872          * this device unaligned.
873          */
874         .min_access_size = 4,
875         .max_access_size = 4,
876         .unaligned = false,
877     },
878 };
879 
880 static void imx6ul_ccm_init(Object *obj)
881 {
882     DeviceState *dev = DEVICE(obj);
883     SysBusDevice *sd = SYS_BUS_DEVICE(obj);
884     IMX6ULCCMState *s = IMX6UL_CCM(obj);
885 
886     /* initialize a container for the all memory range */
887     memory_region_init(&s->container, OBJECT(dev), TYPE_IMX6UL_CCM, 0x8000);
888 
889     /* We initialize an IO memory region for the CCM part */
890     memory_region_init_io(&s->ioccm, OBJECT(dev), &imx6ul_ccm_ops, s,
891                           TYPE_IMX6UL_CCM ".ccm", CCM_MAX * sizeof(uint32_t));
892 
893     /* Add the CCM as a subregion at offset 0 */
894     memory_region_add_subregion(&s->container, 0, &s->ioccm);
895 
896     /* We initialize an IO memory region for the ANALOG part */
897     memory_region_init_io(&s->ioanalog, OBJECT(dev), &imx6ul_analog_ops, s,
898                           TYPE_IMX6UL_CCM ".analog",
899                           CCM_ANALOG_MAX * sizeof(uint32_t));
900 
901     /* Add the ANALOG as a subregion at offset 0x4000 */
902     memory_region_add_subregion(&s->container, 0x4000, &s->ioanalog);
903 
904     sysbus_init_mmio(sd, &s->container);
905 }
906 
907 static void imx6ul_ccm_class_init(ObjectClass *klass, void *data)
908 {
909     DeviceClass *dc = DEVICE_CLASS(klass);
910     IMXCCMClass *ccm = IMX_CCM_CLASS(klass);
911 
912     dc->reset = imx6ul_ccm_reset;
913     dc->vmsd = &vmstate_imx6ul_ccm;
914     dc->desc = "i.MX6UL Clock Control Module";
915 
916     ccm->get_clock_frequency = imx6ul_ccm_get_clock_frequency;
917 }
918 
919 static const TypeInfo imx6ul_ccm_info = {
920     .name          = TYPE_IMX6UL_CCM,
921     .parent        = TYPE_IMX_CCM,
922     .instance_size = sizeof(IMX6ULCCMState),
923     .instance_init = imx6ul_ccm_init,
924     .class_init    = imx6ul_ccm_class_init,
925 };
926 
927 static void imx6ul_ccm_register_types(void)
928 {
929     type_register_static(&imx6ul_ccm_info);
930 }
931 
932 type_init(imx6ul_ccm_register_types)
933