1cb54d868SJean-Christophe Dubois /*
2cb54d868SJean-Christophe Dubois * IMX31 Clock Control Module
3cb54d868SJean-Christophe Dubois *
4cb54d868SJean-Christophe Dubois * Copyright (C) 2012 NICTA
5cb54d868SJean-Christophe Dubois * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
6cb54d868SJean-Christophe Dubois *
7cb54d868SJean-Christophe Dubois * This work is licensed under the terms of the GNU GPL, version 2 or later.
8cb54d868SJean-Christophe Dubois * See the COPYING file in the top-level directory.
9cb54d868SJean-Christophe Dubois *
10cb54d868SJean-Christophe Dubois * To get the timer frequencies right, we need to emulate at least part of
11cb54d868SJean-Christophe Dubois * the i.MX31 CCM.
12cb54d868SJean-Christophe Dubois */
13cb54d868SJean-Christophe Dubois
148ef94f0bSPeter Maydell #include "qemu/osdep.h"
15cb54d868SJean-Christophe Dubois #include "hw/misc/imx31_ccm.h"
16d6454270SMarkus Armbruster #include "migration/vmstate.h"
1703dd024fSPaolo Bonzini #include "qemu/log.h"
180b8fa32fSMarkus Armbruster #include "qemu/module.h"
19cb54d868SJean-Christophe Dubois
20cb54d868SJean-Christophe Dubois #define CKIH_FREQ 26000000 /* 26MHz crystal input */
21cb54d868SJean-Christophe Dubois
22cb54d868SJean-Christophe Dubois #ifndef DEBUG_IMX31_CCM
23cb54d868SJean-Christophe Dubois #define DEBUG_IMX31_CCM 0
24cb54d868SJean-Christophe Dubois #endif
25cb54d868SJean-Christophe Dubois
26cb54d868SJean-Christophe Dubois #define DPRINTF(fmt, args...) \
27cb54d868SJean-Christophe Dubois do { \
28cb54d868SJean-Christophe Dubois if (DEBUG_IMX31_CCM) { \
29cb54d868SJean-Christophe Dubois fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX31_CCM, \
30cb54d868SJean-Christophe Dubois __func__, ##args); \
31cb54d868SJean-Christophe Dubois } \
32cb54d868SJean-Christophe Dubois } while (0)
33cb54d868SJean-Christophe Dubois
imx31_ccm_reg_name(uint32_t reg)34d675765aSPeter Maydell static const char *imx31_ccm_reg_name(uint32_t reg)
35cb54d868SJean-Christophe Dubois {
36fea01f96SJean-Christophe DUBOIS static char unknown[20];
37fea01f96SJean-Christophe DUBOIS
38cb54d868SJean-Christophe Dubois switch (reg) {
39fea01f96SJean-Christophe DUBOIS case IMX31_CCM_CCMR_REG:
40cb54d868SJean-Christophe Dubois return "CCMR";
41fea01f96SJean-Christophe DUBOIS case IMX31_CCM_PDR0_REG:
42cb54d868SJean-Christophe Dubois return "PDR0";
43fea01f96SJean-Christophe DUBOIS case IMX31_CCM_PDR1_REG:
44cb54d868SJean-Christophe Dubois return "PDR1";
45fea01f96SJean-Christophe DUBOIS case IMX31_CCM_RCSR_REG:
46cb54d868SJean-Christophe Dubois return "RCSR";
47fea01f96SJean-Christophe DUBOIS case IMX31_CCM_MPCTL_REG:
48cb54d868SJean-Christophe Dubois return "MPCTL";
49fea01f96SJean-Christophe DUBOIS case IMX31_CCM_UPCTL_REG:
50cb54d868SJean-Christophe Dubois return "UPCTL";
51fea01f96SJean-Christophe DUBOIS case IMX31_CCM_SPCTL_REG:
52cb54d868SJean-Christophe Dubois return "SPCTL";
53fea01f96SJean-Christophe DUBOIS case IMX31_CCM_COSR_REG:
54cb54d868SJean-Christophe Dubois return "COSR";
55fea01f96SJean-Christophe DUBOIS case IMX31_CCM_CGR0_REG:
56cb54d868SJean-Christophe Dubois return "CGR0";
57fea01f96SJean-Christophe DUBOIS case IMX31_CCM_CGR1_REG:
58cb54d868SJean-Christophe Dubois return "CGR1";
59fea01f96SJean-Christophe DUBOIS case IMX31_CCM_CGR2_REG:
60cb54d868SJean-Christophe Dubois return "CGR2";
61fea01f96SJean-Christophe DUBOIS case IMX31_CCM_WIMR_REG:
62cb54d868SJean-Christophe Dubois return "WIMR";
63fea01f96SJean-Christophe DUBOIS case IMX31_CCM_LDC_REG:
64cb54d868SJean-Christophe Dubois return "LDC";
65fea01f96SJean-Christophe DUBOIS case IMX31_CCM_DCVR0_REG:
66cb54d868SJean-Christophe Dubois return "DCVR0";
67fea01f96SJean-Christophe DUBOIS case IMX31_CCM_DCVR1_REG:
68cb54d868SJean-Christophe Dubois return "DCVR1";
69fea01f96SJean-Christophe DUBOIS case IMX31_CCM_DCVR2_REG:
70cb54d868SJean-Christophe Dubois return "DCVR2";
71fea01f96SJean-Christophe DUBOIS case IMX31_CCM_DCVR3_REG:
72cb54d868SJean-Christophe Dubois return "DCVR3";
73fea01f96SJean-Christophe DUBOIS case IMX31_CCM_LTR0_REG:
74cb54d868SJean-Christophe Dubois return "LTR0";
75fea01f96SJean-Christophe DUBOIS case IMX31_CCM_LTR1_REG:
76cb54d868SJean-Christophe Dubois return "LTR1";
77fea01f96SJean-Christophe DUBOIS case IMX31_CCM_LTR2_REG:
78cb54d868SJean-Christophe Dubois return "LTR2";
79fea01f96SJean-Christophe DUBOIS case IMX31_CCM_LTR3_REG:
80cb54d868SJean-Christophe Dubois return "LTR3";
81fea01f96SJean-Christophe DUBOIS case IMX31_CCM_LTBR0_REG:
82cb54d868SJean-Christophe Dubois return "LTBR0";
83fea01f96SJean-Christophe DUBOIS case IMX31_CCM_LTBR1_REG:
84cb54d868SJean-Christophe Dubois return "LTBR1";
85fea01f96SJean-Christophe DUBOIS case IMX31_CCM_PMCR0_REG:
86cb54d868SJean-Christophe Dubois return "PMCR0";
87fea01f96SJean-Christophe DUBOIS case IMX31_CCM_PMCR1_REG:
88cb54d868SJean-Christophe Dubois return "PMCR1";
89fea01f96SJean-Christophe DUBOIS case IMX31_CCM_PDR2_REG:
90cb54d868SJean-Christophe Dubois return "PDR2";
91cb54d868SJean-Christophe Dubois default:
92ca4af17cSPhilippe Mathieu-Daudé snprintf(unknown, sizeof(unknown), "[%u ?]", reg);
93fea01f96SJean-Christophe DUBOIS return unknown;
94cb54d868SJean-Christophe Dubois }
95cb54d868SJean-Christophe Dubois }
96cb54d868SJean-Christophe Dubois
97cb54d868SJean-Christophe Dubois static const VMStateDescription vmstate_imx31_ccm = {
98cb54d868SJean-Christophe Dubois .name = TYPE_IMX31_CCM,
99fea01f96SJean-Christophe DUBOIS .version_id = 2,
100fea01f96SJean-Christophe DUBOIS .minimum_version_id = 2,
101e4ea952fSRichard Henderson .fields = (const VMStateField[]) {
102fea01f96SJean-Christophe DUBOIS VMSTATE_UINT32_ARRAY(reg, IMX31CCMState, IMX31_CCM_MAX_REG),
103cb54d868SJean-Christophe Dubois VMSTATE_END_OF_LIST()
104cb54d868SJean-Christophe Dubois },
105cb54d868SJean-Christophe Dubois };
106cb54d868SJean-Christophe Dubois
imx31_ccm_get_pll_ref_clk(IMXCCMState * dev)107cb54d868SJean-Christophe Dubois static uint32_t imx31_ccm_get_pll_ref_clk(IMXCCMState *dev)
108cb54d868SJean-Christophe Dubois {
109cb54d868SJean-Christophe Dubois uint32_t freq = 0;
110cb54d868SJean-Christophe Dubois IMX31CCMState *s = IMX31_CCM(dev);
111cb54d868SJean-Christophe Dubois
112fea01f96SJean-Christophe DUBOIS if ((s->reg[IMX31_CCM_CCMR_REG] & CCMR_PRCS) == 2) {
113fea01f96SJean-Christophe DUBOIS if (s->reg[IMX31_CCM_CCMR_REG] & CCMR_FPME) {
114cb54d868SJean-Christophe Dubois freq = CKIL_FREQ;
115fea01f96SJean-Christophe DUBOIS if (s->reg[IMX31_CCM_CCMR_REG] & CCMR_FPMF) {
116cb54d868SJean-Christophe Dubois freq *= 1024;
117cb54d868SJean-Christophe Dubois }
118cb54d868SJean-Christophe Dubois }
119cb54d868SJean-Christophe Dubois } else {
120cb54d868SJean-Christophe Dubois freq = CKIH_FREQ;
121cb54d868SJean-Christophe Dubois }
122cb54d868SJean-Christophe Dubois
123a88ae037SAlex Chen DPRINTF("freq = %u\n", freq);
124cb54d868SJean-Christophe Dubois
125cb54d868SJean-Christophe Dubois return freq;
126cb54d868SJean-Christophe Dubois }
127cb54d868SJean-Christophe Dubois
imx31_ccm_get_mpll_clk(IMXCCMState * dev)128cb54d868SJean-Christophe Dubois static uint32_t imx31_ccm_get_mpll_clk(IMXCCMState *dev)
129cb54d868SJean-Christophe Dubois {
130cb54d868SJean-Christophe Dubois uint32_t freq;
131cb54d868SJean-Christophe Dubois IMX31CCMState *s = IMX31_CCM(dev);
132cb54d868SJean-Christophe Dubois
133fea01f96SJean-Christophe DUBOIS freq = imx_ccm_calc_pll(s->reg[IMX31_CCM_MPCTL_REG],
134fea01f96SJean-Christophe DUBOIS imx31_ccm_get_pll_ref_clk(dev));
135cb54d868SJean-Christophe Dubois
136a88ae037SAlex Chen DPRINTF("freq = %u\n", freq);
137cb54d868SJean-Christophe Dubois
138cb54d868SJean-Christophe Dubois return freq;
139cb54d868SJean-Christophe Dubois }
140cb54d868SJean-Christophe Dubois
imx31_ccm_get_mcu_main_clk(IMXCCMState * dev)141cb54d868SJean-Christophe Dubois static uint32_t imx31_ccm_get_mcu_main_clk(IMXCCMState *dev)
142cb54d868SJean-Christophe Dubois {
143cb54d868SJean-Christophe Dubois uint32_t freq;
144cb54d868SJean-Christophe Dubois IMX31CCMState *s = IMX31_CCM(dev);
145cb54d868SJean-Christophe Dubois
146fea01f96SJean-Christophe DUBOIS if ((s->reg[IMX31_CCM_CCMR_REG] & CCMR_MDS) ||
147fea01f96SJean-Christophe DUBOIS !(s->reg[IMX31_CCM_CCMR_REG] & CCMR_MPE)) {
148cb54d868SJean-Christophe Dubois freq = imx31_ccm_get_pll_ref_clk(dev);
149cb54d868SJean-Christophe Dubois } else {
150cb54d868SJean-Christophe Dubois freq = imx31_ccm_get_mpll_clk(dev);
151cb54d868SJean-Christophe Dubois }
152cb54d868SJean-Christophe Dubois
153a88ae037SAlex Chen DPRINTF("freq = %u\n", freq);
154cb54d868SJean-Christophe Dubois
155cb54d868SJean-Christophe Dubois return freq;
156cb54d868SJean-Christophe Dubois }
157cb54d868SJean-Christophe Dubois
imx31_ccm_get_hclk_clk(IMXCCMState * dev)158cb54d868SJean-Christophe Dubois static uint32_t imx31_ccm_get_hclk_clk(IMXCCMState *dev)
159cb54d868SJean-Christophe Dubois {
160cb54d868SJean-Christophe Dubois uint32_t freq;
161cb54d868SJean-Christophe Dubois IMX31CCMState *s = IMX31_CCM(dev);
162cb54d868SJean-Christophe Dubois
163fea01f96SJean-Christophe DUBOIS freq = imx31_ccm_get_mcu_main_clk(dev)
164fea01f96SJean-Christophe DUBOIS / (1 + EXTRACT(s->reg[IMX31_CCM_PDR0_REG], MAX));
165cb54d868SJean-Christophe Dubois
166a88ae037SAlex Chen DPRINTF("freq = %u\n", freq);
167cb54d868SJean-Christophe Dubois
168cb54d868SJean-Christophe Dubois return freq;
169cb54d868SJean-Christophe Dubois }
170cb54d868SJean-Christophe Dubois
imx31_ccm_get_ipg_clk(IMXCCMState * dev)171cb54d868SJean-Christophe Dubois static uint32_t imx31_ccm_get_ipg_clk(IMXCCMState *dev)
172cb54d868SJean-Christophe Dubois {
173cb54d868SJean-Christophe Dubois uint32_t freq;
174cb54d868SJean-Christophe Dubois IMX31CCMState *s = IMX31_CCM(dev);
175cb54d868SJean-Christophe Dubois
176fea01f96SJean-Christophe DUBOIS freq = imx31_ccm_get_hclk_clk(dev)
177fea01f96SJean-Christophe DUBOIS / (1 + EXTRACT(s->reg[IMX31_CCM_PDR0_REG], IPG));
178cb54d868SJean-Christophe Dubois
179a88ae037SAlex Chen DPRINTF("freq = %u\n", freq);
180cb54d868SJean-Christophe Dubois
181cb54d868SJean-Christophe Dubois return freq;
182cb54d868SJean-Christophe Dubois }
183cb54d868SJean-Christophe Dubois
imx31_ccm_get_clock_frequency(IMXCCMState * dev,IMXClk clock)184cb54d868SJean-Christophe Dubois static uint32_t imx31_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
185cb54d868SJean-Christophe Dubois {
186cb54d868SJean-Christophe Dubois uint32_t freq = 0;
187cb54d868SJean-Christophe Dubois
188cb54d868SJean-Christophe Dubois switch (clock) {
189c91a5883SJean-Christophe Dubois case CLK_NONE:
190cb54d868SJean-Christophe Dubois break;
191cb54d868SJean-Christophe Dubois case CLK_IPG:
192d552f675SJean-Christophe Dubois case CLK_IPG_HIGH:
193cb54d868SJean-Christophe Dubois freq = imx31_ccm_get_ipg_clk(dev);
194cb54d868SJean-Christophe Dubois break;
195cb54d868SJean-Christophe Dubois case CLK_32k:
196cb54d868SJean-Christophe Dubois freq = CKIL_FREQ;
197cb54d868SJean-Christophe Dubois break;
198cb54d868SJean-Christophe Dubois default:
199cb54d868SJean-Christophe Dubois qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: unsupported clock %d\n",
200cb54d868SJean-Christophe Dubois TYPE_IMX31_CCM, __func__, clock);
201cb54d868SJean-Christophe Dubois break;
202cb54d868SJean-Christophe Dubois }
203cb54d868SJean-Christophe Dubois
204a88ae037SAlex Chen DPRINTF("Clock = %d) = %u\n", clock, freq);
205cb54d868SJean-Christophe Dubois
206cb54d868SJean-Christophe Dubois return freq;
207cb54d868SJean-Christophe Dubois }
208cb54d868SJean-Christophe Dubois
imx31_ccm_reset(DeviceState * dev)209cb54d868SJean-Christophe Dubois static void imx31_ccm_reset(DeviceState *dev)
210cb54d868SJean-Christophe Dubois {
211cb54d868SJean-Christophe Dubois IMX31CCMState *s = IMX31_CCM(dev);
212cb54d868SJean-Christophe Dubois
213cb54d868SJean-Christophe Dubois DPRINTF("()\n");
214cb54d868SJean-Christophe Dubois
215fea01f96SJean-Christophe DUBOIS memset(s->reg, 0, sizeof(uint32_t) * IMX31_CCM_MAX_REG);
216fea01f96SJean-Christophe DUBOIS
217fea01f96SJean-Christophe DUBOIS s->reg[IMX31_CCM_CCMR_REG] = 0x074b0b7d;
218fea01f96SJean-Christophe DUBOIS s->reg[IMX31_CCM_PDR0_REG] = 0xff870b48;
219fea01f96SJean-Christophe DUBOIS s->reg[IMX31_CCM_PDR1_REG] = 0x49fcfe7f;
220fea01f96SJean-Christophe DUBOIS s->reg[IMX31_CCM_RCSR_REG] = 0x007f0000;
221fea01f96SJean-Christophe DUBOIS s->reg[IMX31_CCM_MPCTL_REG] = 0x04001800;
222fea01f96SJean-Christophe DUBOIS s->reg[IMX31_CCM_UPCTL_REG] = 0x04051c03;
223fea01f96SJean-Christophe DUBOIS s->reg[IMX31_CCM_SPCTL_REG] = 0x04043001;
224fea01f96SJean-Christophe DUBOIS s->reg[IMX31_CCM_COSR_REG] = 0x00000280;
225fea01f96SJean-Christophe DUBOIS s->reg[IMX31_CCM_CGR0_REG] = 0xffffffff;
226fea01f96SJean-Christophe DUBOIS s->reg[IMX31_CCM_CGR1_REG] = 0xffffffff;
227fea01f96SJean-Christophe DUBOIS s->reg[IMX31_CCM_CGR2_REG] = 0xffffffff;
228fea01f96SJean-Christophe DUBOIS s->reg[IMX31_CCM_WIMR_REG] = 0xffffffff;
229fea01f96SJean-Christophe DUBOIS s->reg[IMX31_CCM_LTR1_REG] = 0x00004040;
230fea01f96SJean-Christophe DUBOIS s->reg[IMX31_CCM_PMCR0_REG] = 0x80209828;
231fea01f96SJean-Christophe DUBOIS s->reg[IMX31_CCM_PMCR1_REG] = 0x00aa0000;
232fea01f96SJean-Christophe DUBOIS s->reg[IMX31_CCM_PDR2_REG] = 0x00000285;
233cb54d868SJean-Christophe Dubois }
234cb54d868SJean-Christophe Dubois
imx31_ccm_read(void * opaque,hwaddr offset,unsigned size)235cb54d868SJean-Christophe Dubois static uint64_t imx31_ccm_read(void *opaque, hwaddr offset, unsigned size)
236cb54d868SJean-Christophe Dubois {
2373a87d009SPeter Maydell uint32_t value = 0;
238cb54d868SJean-Christophe Dubois IMX31CCMState *s = (IMX31CCMState *)opaque;
239cb54d868SJean-Christophe Dubois
240fea01f96SJean-Christophe DUBOIS if ((offset >> 2) < IMX31_CCM_MAX_REG) {
241fea01f96SJean-Christophe DUBOIS value = s->reg[offset >> 2];
242fea01f96SJean-Christophe DUBOIS } else {
243cb54d868SJean-Christophe Dubois qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
244cb54d868SJean-Christophe Dubois HWADDR_PRIx "\n", TYPE_IMX31_CCM, __func__, offset);
245cb54d868SJean-Christophe Dubois }
246cb54d868SJean-Christophe Dubois
247cb54d868SJean-Christophe Dubois DPRINTF("reg[%s] => 0x%" PRIx32 "\n", imx31_ccm_reg_name(offset >> 2),
248cb54d868SJean-Christophe Dubois value);
249cb54d868SJean-Christophe Dubois
250cb54d868SJean-Christophe Dubois return (uint64_t)value;
251cb54d868SJean-Christophe Dubois }
252cb54d868SJean-Christophe Dubois
imx31_ccm_write(void * opaque,hwaddr offset,uint64_t value,unsigned size)253cb54d868SJean-Christophe Dubois static void imx31_ccm_write(void *opaque, hwaddr offset, uint64_t value,
254cb54d868SJean-Christophe Dubois unsigned size)
255cb54d868SJean-Christophe Dubois {
256cb54d868SJean-Christophe Dubois IMX31CCMState *s = (IMX31CCMState *)opaque;
257cb54d868SJean-Christophe Dubois
258cb54d868SJean-Christophe Dubois DPRINTF("reg[%s] <= 0x%" PRIx32 "\n", imx31_ccm_reg_name(offset >> 2),
259cb54d868SJean-Christophe Dubois (uint32_t)value);
260cb54d868SJean-Christophe Dubois
261cb54d868SJean-Christophe Dubois switch (offset >> 2) {
262fea01f96SJean-Christophe DUBOIS case IMX31_CCM_CCMR_REG:
263fea01f96SJean-Christophe DUBOIS s->reg[IMX31_CCM_CCMR_REG] = CCMR_FPMF | (value & 0x3b6fdfff);
264cb54d868SJean-Christophe Dubois break;
265fea01f96SJean-Christophe DUBOIS case IMX31_CCM_PDR0_REG:
266fea01f96SJean-Christophe DUBOIS s->reg[IMX31_CCM_PDR0_REG] = value & 0xff9f3fff;
267cb54d868SJean-Christophe Dubois break;
268fea01f96SJean-Christophe DUBOIS case IMX31_CCM_PDR1_REG:
269fea01f96SJean-Christophe DUBOIS s->reg[IMX31_CCM_PDR1_REG] = value;
270cb54d868SJean-Christophe Dubois break;
271fea01f96SJean-Christophe DUBOIS case IMX31_CCM_MPCTL_REG:
272fea01f96SJean-Christophe DUBOIS s->reg[IMX31_CCM_MPCTL_REG] = value & 0xbfff3fff;
273cb54d868SJean-Christophe Dubois break;
274fea01f96SJean-Christophe DUBOIS case IMX31_CCM_SPCTL_REG:
275fea01f96SJean-Christophe DUBOIS s->reg[IMX31_CCM_SPCTL_REG] = value & 0xbfff3fff;
276cb54d868SJean-Christophe Dubois break;
277fea01f96SJean-Christophe DUBOIS case IMX31_CCM_CGR0_REG:
278fea01f96SJean-Christophe DUBOIS s->reg[IMX31_CCM_CGR0_REG] = value;
279cb54d868SJean-Christophe Dubois break;
280fea01f96SJean-Christophe DUBOIS case IMX31_CCM_CGR1_REG:
281fea01f96SJean-Christophe DUBOIS s->reg[IMX31_CCM_CGR1_REG] = value;
282cb54d868SJean-Christophe Dubois break;
283fea01f96SJean-Christophe DUBOIS case IMX31_CCM_CGR2_REG:
284fea01f96SJean-Christophe DUBOIS s->reg[IMX31_CCM_CGR2_REG] = value;
285cb54d868SJean-Christophe Dubois break;
286cb54d868SJean-Christophe Dubois default:
287cb54d868SJean-Christophe Dubois qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
288cb54d868SJean-Christophe Dubois HWADDR_PRIx "\n", TYPE_IMX31_CCM, __func__, offset);
289cb54d868SJean-Christophe Dubois break;
290cb54d868SJean-Christophe Dubois }
291cb54d868SJean-Christophe Dubois }
292cb54d868SJean-Christophe Dubois
293cb54d868SJean-Christophe Dubois static const struct MemoryRegionOps imx31_ccm_ops = {
294cb54d868SJean-Christophe Dubois .read = imx31_ccm_read,
295cb54d868SJean-Christophe Dubois .write = imx31_ccm_write,
296cb54d868SJean-Christophe Dubois .endianness = DEVICE_NATIVE_ENDIAN,
297cb54d868SJean-Christophe Dubois .valid = {
298cb54d868SJean-Christophe Dubois /*
299cb54d868SJean-Christophe Dubois * Our device would not work correctly if the guest was doing
300cb54d868SJean-Christophe Dubois * unaligned access. This might not be a limitation on the real
301cb54d868SJean-Christophe Dubois * device but in practice there is no reason for a guest to access
302cb54d868SJean-Christophe Dubois * this device unaligned.
303cb54d868SJean-Christophe Dubois */
304cb54d868SJean-Christophe Dubois .min_access_size = 4,
305cb54d868SJean-Christophe Dubois .max_access_size = 4,
306cb54d868SJean-Christophe Dubois .unaligned = false,
307cb54d868SJean-Christophe Dubois },
308cb54d868SJean-Christophe Dubois
309cb54d868SJean-Christophe Dubois };
310cb54d868SJean-Christophe Dubois
imx31_ccm_init(Object * obj)311cb54d868SJean-Christophe Dubois static void imx31_ccm_init(Object *obj)
312cb54d868SJean-Christophe Dubois {
313cb54d868SJean-Christophe Dubois DeviceState *dev = DEVICE(obj);
314cb54d868SJean-Christophe Dubois SysBusDevice *sd = SYS_BUS_DEVICE(obj);
315cb54d868SJean-Christophe Dubois IMX31CCMState *s = IMX31_CCM(obj);
316cb54d868SJean-Christophe Dubois
317cb54d868SJean-Christophe Dubois memory_region_init_io(&s->iomem, OBJECT(dev), &imx31_ccm_ops, s,
318cb54d868SJean-Christophe Dubois TYPE_IMX31_CCM, 0x1000);
319cb54d868SJean-Christophe Dubois sysbus_init_mmio(sd, &s->iomem);
320cb54d868SJean-Christophe Dubois }
321cb54d868SJean-Christophe Dubois
imx31_ccm_class_init(ObjectClass * klass,void * data)322cb54d868SJean-Christophe Dubois static void imx31_ccm_class_init(ObjectClass *klass, void *data)
323cb54d868SJean-Christophe Dubois {
324cb54d868SJean-Christophe Dubois DeviceClass *dc = DEVICE_CLASS(klass);
325cb54d868SJean-Christophe Dubois IMXCCMClass *ccm = IMX_CCM_CLASS(klass);
326cb54d868SJean-Christophe Dubois
327*e3d08143SPeter Maydell device_class_set_legacy_reset(dc, imx31_ccm_reset);
328cb54d868SJean-Christophe Dubois dc->vmsd = &vmstate_imx31_ccm;
329cb54d868SJean-Christophe Dubois dc->desc = "i.MX31 Clock Control Module";
330cb54d868SJean-Christophe Dubois
331cb54d868SJean-Christophe Dubois ccm->get_clock_frequency = imx31_ccm_get_clock_frequency;
332cb54d868SJean-Christophe Dubois }
333cb54d868SJean-Christophe Dubois
334cb54d868SJean-Christophe Dubois static const TypeInfo imx31_ccm_info = {
335cb54d868SJean-Christophe Dubois .name = TYPE_IMX31_CCM,
336cb54d868SJean-Christophe Dubois .parent = TYPE_IMX_CCM,
337cb54d868SJean-Christophe Dubois .instance_size = sizeof(IMX31CCMState),
338cb54d868SJean-Christophe Dubois .instance_init = imx31_ccm_init,
339cb54d868SJean-Christophe Dubois .class_init = imx31_ccm_class_init,
340cb54d868SJean-Christophe Dubois };
341cb54d868SJean-Christophe Dubois
imx31_ccm_register_types(void)342cb54d868SJean-Christophe Dubois static void imx31_ccm_register_types(void)
343cb54d868SJean-Christophe Dubois {
344cb54d868SJean-Christophe Dubois type_register_static(&imx31_ccm_info);
345cb54d868SJean-Christophe Dubois }
346cb54d868SJean-Christophe Dubois
347cb54d868SJean-Christophe Dubois type_init(imx31_ccm_register_types)
348