xref: /openbmc/qemu/hw/misc/imx31_ccm.c (revision 9967e4fec0dc6c0157f37574dd33ddd03ca3bee8)
1 /*
2  * IMX31 Clock Control Module
3  *
4  * Copyright (C) 2012 NICTA
5  * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
6  *
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.
9  *
10  * To get the timer frequencies right, we need to emulate at least part of
11  * the i.MX31 CCM.
12  */
13 
14 #include "hw/misc/imx31_ccm.h"
15 
16 #define CKIH_FREQ 26000000 /* 26MHz crystal input */
17 
18 #ifndef DEBUG_IMX31_CCM
19 #define DEBUG_IMX31_CCM 0
20 #endif
21 
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)
29 
30 static char const *imx31_ccm_reg_name(uint32_t reg)
31 {
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 "???";
87     }
88 }
89 
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()
104     },
105 };
106 
107 static uint32_t imx31_ccm_get_pll_ref_clk(IMXCCMState *dev)
108 {
109     uint32_t freq = 0;
110     IMX31CCMState *s = IMX31_CCM(dev);
111 
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;
117             }
118         }
119     } else {
120         freq = CKIH_FREQ;
121     }
122 
123     DPRINTF("freq = %d\n", freq);
124 
125     return freq;
126 }
127 
128 static uint32_t imx31_ccm_get_mpll_clk(IMXCCMState *dev)
129 {
130     uint32_t freq;
131     IMX31CCMState *s = IMX31_CCM(dev);
132 
133     freq = imx_ccm_calc_pll(s->mpctl, imx31_ccm_get_pll_ref_clk(dev));
134 
135     DPRINTF("freq = %d\n", freq);
136 
137     return freq;
138 }
139 
140 static uint32_t imx31_ccm_get_mcu_main_clk(IMXCCMState *dev)
141 {
142     uint32_t freq;
143     IMX31CCMState *s = IMX31_CCM(dev);
144 
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);
149     }
150 
151     DPRINTF("freq = %d\n", freq);
152 
153     return freq;
154 }
155 
156 static uint32_t imx31_ccm_get_mcu_clk(IMXCCMState *dev)
157 {
158     uint32_t freq;
159     IMX31CCMState *s = IMX31_CCM(dev);
160 
161     freq = imx31_ccm_get_mcu_main_clk(dev) / (1 + EXTRACT(s->pdr0, MCU));
162 
163     DPRINTF("freq = %d\n", freq);
164 
165     return freq;
166 }
167 
168 static uint32_t imx31_ccm_get_hsp_clk(IMXCCMState *dev)
169 {
170     uint32_t freq;
171     IMX31CCMState *s = IMX31_CCM(dev);
172 
173     freq = imx31_ccm_get_mcu_main_clk(dev) / (1 + EXTRACT(s->pdr0, HSP));
174 
175     DPRINTF("freq = %d\n", freq);
176 
177     return freq;
178 }
179 
180 static uint32_t imx31_ccm_get_hclk_clk(IMXCCMState *dev)
181 {
182     uint32_t freq;
183     IMX31CCMState *s = IMX31_CCM(dev);
184 
185     freq = imx31_ccm_get_mcu_main_clk(dev) / (1 + EXTRACT(s->pdr0, MAX));
186 
187     DPRINTF("freq = %d\n", freq);
188 
189     return freq;
190 }
191 
192 static uint32_t imx31_ccm_get_ipg_clk(IMXCCMState *dev)
193 {
194     uint32_t freq;
195     IMX31CCMState *s = IMX31_CCM(dev);
196 
197     freq = imx31_ccm_get_hclk_clk(dev) / (1 + EXTRACT(s->pdr0, IPG));
198 
199     DPRINTF("freq = %d\n", freq);
200 
201     return freq;
202 }
203 
204 static uint32_t imx31_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
205 {
206     uint32_t freq = 0;
207 
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;
227     }
228 
229     DPRINTF("Clock = %d) = %d\n", clock, freq);
230 
231     return freq;
232 }
233 
234 static void imx31_ccm_reset(DeviceState *dev)
235 {
236     IMX31CCMState *s = IMX31_CCM(dev);
237 
238     DPRINTF("()\n");
239 
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;
248 }
249 
250 static uint64_t imx31_ccm_read(void *opaque, hwaddr offset, unsigned size)
251 {
252     uint32 value = 0;
253     IMX31CCMState *s = (IMX31CCMState *)opaque;
254 
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;
290     }
291 
292     DPRINTF("reg[%s] => 0x%" PRIx32 "\n", imx31_ccm_reg_name(offset >> 2),
293             value);
294 
295     return (uint64_t)value;
296 }
297 
298 static void imx31_ccm_write(void *opaque, hwaddr offset, uint64_t value,
299                             unsigned size)
300 {
301     IMX31CCMState *s = (IMX31CCMState *)opaque;
302 
303     DPRINTF("reg[%s] <= 0x%" PRIx32 "\n", imx31_ccm_reg_name(offset >> 2),
304             (uint32_t)value);
305 
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;
335     }
336 }
337 
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 = {
343         /*
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.
348          */
349         .min_access_size = 4,
350         .max_access_size = 4,
351         .unaligned = false,
352     },
353 
354 };
355 
356 static void imx31_ccm_init(Object *obj)
357 {
358     DeviceState *dev = DEVICE(obj);
359     SysBusDevice *sd = SYS_BUS_DEVICE(obj);
360     IMX31CCMState *s = IMX31_CCM(obj);
361 
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);
365 }
366 
367 static void imx31_ccm_class_init(ObjectClass *klass, void *data)
368 {
369     DeviceClass *dc  = DEVICE_CLASS(klass);
370     IMXCCMClass *ccm = IMX_CCM_CLASS(klass);
371 
372     dc->reset = imx31_ccm_reset;
373     dc->vmsd  = &vmstate_imx31_ccm;
374     dc->desc  = "i.MX31 Clock Control Module";
375 
376     ccm->get_clock_frequency = imx31_ccm_get_clock_frequency;
377 }
378 
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,
385 };
386 
387 static void imx31_ccm_register_types(void)
388 {
389     type_register_static(&imx31_ccm_info);
390 }
391 
392 type_init(imx31_ccm_register_types)
393