xref: /openbmc/qemu/hw/arm/fsl-imx6ul.c (revision 6620801f)
1 /*
2  * Copyright (c) 2018 Jean-Christophe Dubois <jcd@tribudubois.net>
3  *
4  * i.MX6UL SOC emulation.
5  *
6  * Based on hw/arm/fsl-imx7.c
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  */
18 
19 #include "qemu/osdep.h"
20 #include "qapi/error.h"
21 #include "hw/arm/fsl-imx6ul.h"
22 #include "hw/misc/unimp.h"
23 #include "hw/boards.h"
24 #include "sysemu/sysemu.h"
25 #include "qemu/error-report.h"
26 #include "qemu/module.h"
27 
28 #define NAME_SIZE 20
29 
30 static void fsl_imx6ul_init(Object *obj)
31 {
32     FslIMX6ULState *s = FSL_IMX6UL(obj);
33     char name[NAME_SIZE];
34     int i;
35 
36     object_initialize_child(obj, "cpu0", &s->cpu, sizeof(s->cpu),
37                             ARM_CPU_TYPE_NAME("cortex-a7"), &error_abort, NULL);
38 
39     /*
40      * A7MPCORE
41      */
42     sysbus_init_child_obj(obj, "a7mpcore", &s->a7mpcore, sizeof(s->a7mpcore),
43                           TYPE_A15MPCORE_PRIV);
44 
45     /*
46      * CCM
47      */
48     sysbus_init_child_obj(obj, "ccm", &s->ccm, sizeof(s->ccm), TYPE_IMX6UL_CCM);
49 
50     /*
51      * SRC
52      */
53     sysbus_init_child_obj(obj, "src", &s->src, sizeof(s->src), TYPE_IMX6_SRC);
54 
55     /*
56      * GPCv2
57      */
58     sysbus_init_child_obj(obj, "gpcv2", &s->gpcv2, sizeof(s->gpcv2),
59                           TYPE_IMX_GPCV2);
60 
61     /*
62      * SNVS
63      */
64     sysbus_init_child_obj(obj, "snvs", &s->snvs, sizeof(s->snvs),
65                           TYPE_IMX7_SNVS);
66 
67     /*
68      * GPR
69      */
70     sysbus_init_child_obj(obj, "gpr", &s->gpr, sizeof(s->gpr),
71                           TYPE_IMX7_GPR);
72 
73     /*
74      * GPIOs 1 to 5
75      */
76     for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
77         snprintf(name, NAME_SIZE, "gpio%d", i);
78         sysbus_init_child_obj(obj, name, &s->gpio[i], sizeof(s->gpio[i]),
79                               TYPE_IMX_GPIO);
80     }
81 
82     /*
83      * GPT 1, 2
84      */
85     for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
86         snprintf(name, NAME_SIZE, "gpt%d", i);
87         sysbus_init_child_obj(obj, name, &s->gpt[i], sizeof(s->gpt[i]),
88                               TYPE_IMX7_GPT);
89     }
90 
91     /*
92      * EPIT 1, 2
93      */
94     for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
95         snprintf(name, NAME_SIZE, "epit%d", i + 1);
96         sysbus_init_child_obj(obj, name, &s->epit[i], sizeof(s->epit[i]),
97                               TYPE_IMX_EPIT);
98     }
99 
100     /*
101      * eCSPI
102      */
103     for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) {
104         snprintf(name, NAME_SIZE, "spi%d", i + 1);
105         sysbus_init_child_obj(obj, name, &s->spi[i], sizeof(s->spi[i]),
106                               TYPE_IMX_SPI);
107     }
108 
109     /*
110      * I2C
111      */
112     for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) {
113         snprintf(name, NAME_SIZE, "i2c%d", i + 1);
114         sysbus_init_child_obj(obj, name, &s->i2c[i], sizeof(s->i2c[i]),
115                               TYPE_IMX_I2C);
116     }
117 
118     /*
119      * UART
120      */
121     for (i = 0; i < FSL_IMX6UL_NUM_UARTS; i++) {
122         snprintf(name, NAME_SIZE, "uart%d", i);
123         sysbus_init_child_obj(obj, name, &s->uart[i], sizeof(s->uart[i]),
124                               TYPE_IMX_SERIAL);
125     }
126 
127     /*
128      * Ethernet
129      */
130     for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
131         snprintf(name, NAME_SIZE, "eth%d", i);
132         sysbus_init_child_obj(obj, name, &s->eth[i], sizeof(s->eth[i]),
133                               TYPE_IMX_ENET);
134     }
135 
136     /*
137      * SDHCI
138      */
139     for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
140         snprintf(name, NAME_SIZE, "usdhc%d", i);
141         sysbus_init_child_obj(obj, name, &s->usdhc[i], sizeof(s->usdhc[i]),
142                               TYPE_IMX_USDHC);
143     }
144 
145     /*
146      * Watchdog
147      */
148     for (i = 0; i < FSL_IMX6UL_NUM_WDTS; i++) {
149         snprintf(name, NAME_SIZE, "wdt%d", i);
150         sysbus_init_child_obj(obj, name, &s->wdt[i], sizeof(s->wdt[i]),
151                               TYPE_IMX2_WDT);
152     }
153 }
154 
155 static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
156 {
157     MachineState *ms = MACHINE(qdev_get_machine());
158     FslIMX6ULState *s = FSL_IMX6UL(dev);
159     int i;
160     char name[NAME_SIZE];
161     SysBusDevice *sbd;
162     DeviceState *d;
163 
164     if (ms->smp.cpus > 1) {
165         error_setg(errp, "%s: Only a single CPU is supported (%d requested)",
166                    TYPE_FSL_IMX6UL, ms->smp.cpus);
167         return;
168     }
169 
170     object_property_set_int(OBJECT(&s->cpu), QEMU_PSCI_CONDUIT_SMC,
171                             "psci-conduit", &error_abort);
172     object_property_set_bool(OBJECT(&s->cpu), true,
173                              "realized", &error_abort);
174 
175     /*
176      * A7MPCORE
177      */
178     object_property_set_int(OBJECT(&s->a7mpcore), 1, "num-cpu", &error_abort);
179     object_property_set_int(OBJECT(&s->a7mpcore),
180                             FSL_IMX6UL_MAX_IRQ + GIC_INTERNAL,
181                             "num-irq", &error_abort);
182     object_property_set_bool(OBJECT(&s->a7mpcore), true, "realized",
183                              &error_abort);
184     sysbus_mmio_map(SYS_BUS_DEVICE(&s->a7mpcore), 0, FSL_IMX6UL_A7MPCORE_ADDR);
185 
186     sbd = SYS_BUS_DEVICE(&s->a7mpcore);
187     d = DEVICE(&s->cpu);
188 
189     sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(d, ARM_CPU_IRQ));
190     sysbus_connect_irq(sbd, 1, qdev_get_gpio_in(d, ARM_CPU_FIQ));
191     sysbus_connect_irq(sbd, 2, qdev_get_gpio_in(d, ARM_CPU_VIRQ));
192     sysbus_connect_irq(sbd, 3, qdev_get_gpio_in(d, ARM_CPU_VFIQ));
193 
194     /*
195      * A7MPCORE DAP
196      */
197     create_unimplemented_device("a7mpcore-dap", FSL_IMX6UL_A7MPCORE_DAP_ADDR,
198                                 0x100000);
199 
200     /*
201      * GPT 1, 2
202      */
203     for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
204         static const hwaddr FSL_IMX6UL_GPTn_ADDR[FSL_IMX6UL_NUM_GPTS] = {
205             FSL_IMX6UL_GPT1_ADDR,
206             FSL_IMX6UL_GPT2_ADDR,
207         };
208 
209         static const int FSL_IMX6UL_GPTn_IRQ[FSL_IMX6UL_NUM_GPTS] = {
210             FSL_IMX6UL_GPT1_IRQ,
211             FSL_IMX6UL_GPT2_IRQ,
212         };
213 
214         s->gpt[i].ccm = IMX_CCM(&s->ccm);
215         object_property_set_bool(OBJECT(&s->gpt[i]), true, "realized",
216                                  &error_abort);
217 
218         sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0,
219                         FSL_IMX6UL_GPTn_ADDR[i]);
220 
221         sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0,
222                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
223                                             FSL_IMX6UL_GPTn_IRQ[i]));
224     }
225 
226     /*
227      * EPIT 1, 2
228      */
229     for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
230         static const hwaddr FSL_IMX6UL_EPITn_ADDR[FSL_IMX6UL_NUM_EPITS] = {
231             FSL_IMX6UL_EPIT1_ADDR,
232             FSL_IMX6UL_EPIT2_ADDR,
233         };
234 
235         static const int FSL_IMX6UL_EPITn_IRQ[FSL_IMX6UL_NUM_EPITS] = {
236             FSL_IMX6UL_EPIT1_IRQ,
237             FSL_IMX6UL_EPIT2_IRQ,
238         };
239 
240         s->epit[i].ccm = IMX_CCM(&s->ccm);
241         object_property_set_bool(OBJECT(&s->epit[i]), true, "realized",
242                                  &error_abort);
243 
244         sysbus_mmio_map(SYS_BUS_DEVICE(&s->epit[i]), 0,
245                         FSL_IMX6UL_EPITn_ADDR[i]);
246 
247         sysbus_connect_irq(SYS_BUS_DEVICE(&s->epit[i]), 0,
248                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
249                                             FSL_IMX6UL_EPITn_IRQ[i]));
250     }
251 
252     /*
253      * GPIO
254      */
255     for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
256         static const hwaddr FSL_IMX6UL_GPIOn_ADDR[FSL_IMX6UL_NUM_GPIOS] = {
257             FSL_IMX6UL_GPIO1_ADDR,
258             FSL_IMX6UL_GPIO2_ADDR,
259             FSL_IMX6UL_GPIO3_ADDR,
260             FSL_IMX6UL_GPIO4_ADDR,
261             FSL_IMX6UL_GPIO5_ADDR,
262         };
263 
264         static const int FSL_IMX6UL_GPIOn_LOW_IRQ[FSL_IMX6UL_NUM_GPIOS] = {
265             FSL_IMX6UL_GPIO1_LOW_IRQ,
266             FSL_IMX6UL_GPIO2_LOW_IRQ,
267             FSL_IMX6UL_GPIO3_LOW_IRQ,
268             FSL_IMX6UL_GPIO4_LOW_IRQ,
269             FSL_IMX6UL_GPIO5_LOW_IRQ,
270         };
271 
272         static const int FSL_IMX6UL_GPIOn_HIGH_IRQ[FSL_IMX6UL_NUM_GPIOS] = {
273             FSL_IMX6UL_GPIO1_HIGH_IRQ,
274             FSL_IMX6UL_GPIO2_HIGH_IRQ,
275             FSL_IMX6UL_GPIO3_HIGH_IRQ,
276             FSL_IMX6UL_GPIO4_HIGH_IRQ,
277             FSL_IMX6UL_GPIO5_HIGH_IRQ,
278         };
279 
280         object_property_set_bool(OBJECT(&s->gpio[i]), true, "realized",
281                                  &error_abort);
282 
283         sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0,
284                         FSL_IMX6UL_GPIOn_ADDR[i]);
285 
286         sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0,
287                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
288                                             FSL_IMX6UL_GPIOn_LOW_IRQ[i]));
289 
290         sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 1,
291                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
292                                             FSL_IMX6UL_GPIOn_HIGH_IRQ[i]));
293     }
294 
295     /*
296      * IOMUXC and IOMUXC_GPR
297      */
298     for (i = 0; i < 1; i++) {
299         static const hwaddr FSL_IMX6UL_IOMUXCn_ADDR[FSL_IMX6UL_NUM_IOMUXCS] = {
300             FSL_IMX6UL_IOMUXC_ADDR,
301             FSL_IMX6UL_IOMUXC_GPR_ADDR,
302         };
303 
304         snprintf(name, NAME_SIZE, "iomuxc%d", i);
305         create_unimplemented_device(name, FSL_IMX6UL_IOMUXCn_ADDR[i], 0x4000);
306     }
307 
308     /*
309      * CCM
310      */
311     object_property_set_bool(OBJECT(&s->ccm), true, "realized", &error_abort);
312     sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX6UL_CCM_ADDR);
313 
314     /*
315      * SRC
316      */
317     object_property_set_bool(OBJECT(&s->src), true, "realized", &error_abort);
318     sysbus_mmio_map(SYS_BUS_DEVICE(&s->src), 0, FSL_IMX6UL_SRC_ADDR);
319 
320     /*
321      * GPCv2
322      */
323     object_property_set_bool(OBJECT(&s->gpcv2), true,
324                              "realized", &error_abort);
325     sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpcv2), 0, FSL_IMX6UL_GPC_ADDR);
326 
327     /* Initialize all ECSPI */
328     for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) {
329         static const hwaddr FSL_IMX6UL_SPIn_ADDR[FSL_IMX6UL_NUM_ECSPIS] = {
330             FSL_IMX6UL_ECSPI1_ADDR,
331             FSL_IMX6UL_ECSPI2_ADDR,
332             FSL_IMX6UL_ECSPI3_ADDR,
333             FSL_IMX6UL_ECSPI4_ADDR,
334         };
335 
336         static const int FSL_IMX6UL_SPIn_IRQ[FSL_IMX6UL_NUM_ECSPIS] = {
337             FSL_IMX6UL_ECSPI1_IRQ,
338             FSL_IMX6UL_ECSPI2_IRQ,
339             FSL_IMX6UL_ECSPI3_IRQ,
340             FSL_IMX6UL_ECSPI4_IRQ,
341         };
342 
343         /* Initialize the SPI */
344         object_property_set_bool(OBJECT(&s->spi[i]), true, "realized",
345                                  &error_abort);
346 
347         sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0,
348                         FSL_IMX6UL_SPIn_ADDR[i]);
349 
350         sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0,
351                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
352                                             FSL_IMX6UL_SPIn_IRQ[i]));
353     }
354 
355     /*
356      * I2C
357      */
358     for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) {
359         static const hwaddr FSL_IMX6UL_I2Cn_ADDR[FSL_IMX6UL_NUM_I2CS] = {
360             FSL_IMX6UL_I2C1_ADDR,
361             FSL_IMX6UL_I2C2_ADDR,
362             FSL_IMX6UL_I2C3_ADDR,
363             FSL_IMX6UL_I2C4_ADDR,
364         };
365 
366         static const int FSL_IMX6UL_I2Cn_IRQ[FSL_IMX6UL_NUM_I2CS] = {
367             FSL_IMX6UL_I2C1_IRQ,
368             FSL_IMX6UL_I2C2_IRQ,
369             FSL_IMX6UL_I2C3_IRQ,
370             FSL_IMX6UL_I2C4_IRQ,
371         };
372 
373         object_property_set_bool(OBJECT(&s->i2c[i]), true, "realized",
374                                  &error_abort);
375         sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, FSL_IMX6UL_I2Cn_ADDR[i]);
376 
377         sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
378                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
379                                             FSL_IMX6UL_I2Cn_IRQ[i]));
380     }
381 
382     /*
383      * UART
384      */
385     for (i = 0; i < FSL_IMX6UL_NUM_UARTS; i++) {
386         static const hwaddr FSL_IMX6UL_UARTn_ADDR[FSL_IMX6UL_NUM_UARTS] = {
387             FSL_IMX6UL_UART1_ADDR,
388             FSL_IMX6UL_UART2_ADDR,
389             FSL_IMX6UL_UART3_ADDR,
390             FSL_IMX6UL_UART4_ADDR,
391             FSL_IMX6UL_UART5_ADDR,
392             FSL_IMX6UL_UART6_ADDR,
393             FSL_IMX6UL_UART7_ADDR,
394             FSL_IMX6UL_UART8_ADDR,
395         };
396 
397         static const int FSL_IMX6UL_UARTn_IRQ[FSL_IMX6UL_NUM_UARTS] = {
398             FSL_IMX6UL_UART1_IRQ,
399             FSL_IMX6UL_UART2_IRQ,
400             FSL_IMX6UL_UART3_IRQ,
401             FSL_IMX6UL_UART4_IRQ,
402             FSL_IMX6UL_UART5_IRQ,
403             FSL_IMX6UL_UART6_IRQ,
404             FSL_IMX6UL_UART7_IRQ,
405             FSL_IMX6UL_UART8_IRQ,
406         };
407 
408         qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", serial_hd(i));
409 
410         object_property_set_bool(OBJECT(&s->uart[i]), true, "realized",
411                                  &error_abort);
412 
413         sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0,
414                         FSL_IMX6UL_UARTn_ADDR[i]);
415 
416         sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0,
417                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
418                                             FSL_IMX6UL_UARTn_IRQ[i]));
419     }
420 
421     /*
422      * Ethernet
423      */
424     for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
425         static const hwaddr FSL_IMX6UL_ENETn_ADDR[FSL_IMX6UL_NUM_ETHS] = {
426             FSL_IMX6UL_ENET1_ADDR,
427             FSL_IMX6UL_ENET2_ADDR,
428         };
429 
430         static const int FSL_IMX6UL_ENETn_IRQ[FSL_IMX6UL_NUM_ETHS] = {
431             FSL_IMX6UL_ENET1_IRQ,
432             FSL_IMX6UL_ENET2_IRQ,
433         };
434 
435         static const int FSL_IMX6UL_ENETn_TIMER_IRQ[FSL_IMX6UL_NUM_ETHS] = {
436             FSL_IMX6UL_ENET1_TIMER_IRQ,
437             FSL_IMX6UL_ENET2_TIMER_IRQ,
438         };
439 
440         object_property_set_uint(OBJECT(&s->eth[i]),
441                                  FSL_IMX6UL_ETH_NUM_TX_RINGS,
442                                  "tx-ring-num", &error_abort);
443         qdev_set_nic_properties(DEVICE(&s->eth[i]), &nd_table[i]);
444         object_property_set_bool(OBJECT(&s->eth[i]), true, "realized",
445                                  &error_abort);
446 
447         sysbus_mmio_map(SYS_BUS_DEVICE(&s->eth[i]), 0,
448                         FSL_IMX6UL_ENETn_ADDR[i]);
449 
450         sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 0,
451                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
452                                             FSL_IMX6UL_ENETn_IRQ[i]));
453 
454         sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 1,
455                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
456                                             FSL_IMX6UL_ENETn_TIMER_IRQ[i]));
457     }
458 
459     /*
460      * USDHC
461      */
462     for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
463         static const hwaddr FSL_IMX6UL_USDHCn_ADDR[FSL_IMX6UL_NUM_USDHCS] = {
464             FSL_IMX6UL_USDHC1_ADDR,
465             FSL_IMX6UL_USDHC2_ADDR,
466         };
467 
468         static const int FSL_IMX6UL_USDHCn_IRQ[FSL_IMX6UL_NUM_USDHCS] = {
469             FSL_IMX6UL_USDHC1_IRQ,
470             FSL_IMX6UL_USDHC2_IRQ,
471         };
472 
473         object_property_set_bool(OBJECT(&s->usdhc[i]), true, "realized",
474                                  &error_abort);
475 
476         sysbus_mmio_map(SYS_BUS_DEVICE(&s->usdhc[i]), 0,
477                         FSL_IMX6UL_USDHCn_ADDR[i]);
478 
479         sysbus_connect_irq(SYS_BUS_DEVICE(&s->usdhc[i]), 0,
480                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
481                                             FSL_IMX6UL_USDHCn_IRQ[i]));
482     }
483 
484     /*
485      * SNVS
486      */
487     object_property_set_bool(OBJECT(&s->snvs), true, "realized", &error_abort);
488     sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0, FSL_IMX6UL_SNVS_HP_ADDR);
489 
490     /*
491      * Watchdog
492      */
493     for (i = 0; i < FSL_IMX6UL_NUM_WDTS; i++) {
494         static const hwaddr FSL_IMX6UL_WDOGn_ADDR[FSL_IMX6UL_NUM_WDTS] = {
495             FSL_IMX6UL_WDOG1_ADDR,
496             FSL_IMX6UL_WDOG2_ADDR,
497             FSL_IMX6UL_WDOG3_ADDR,
498         };
499 
500         object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized",
501                                  &error_abort);
502 
503         sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0,
504                         FSL_IMX6UL_WDOGn_ADDR[i]);
505     }
506 
507     /*
508      * GPR
509      */
510     object_property_set_bool(OBJECT(&s->gpr), true, "realized",
511                              &error_abort);
512     sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpr), 0, FSL_IMX6UL_IOMUXC_GPR_ADDR);
513 
514     /*
515      * SDMA
516      */
517     create_unimplemented_device("sdma", FSL_IMX6UL_SDMA_ADDR, 0x4000);
518 
519     /*
520      * APHB_DMA
521      */
522     create_unimplemented_device("aphb_dma", FSL_IMX6UL_APBH_DMA_ADDR,
523                                 FSL_IMX6UL_APBH_DMA_SIZE);
524 
525     /*
526      * ADCs
527      */
528     for (i = 0; i < FSL_IMX6UL_NUM_ADCS; i++) {
529         static const hwaddr FSL_IMX6UL_ADCn_ADDR[FSL_IMX6UL_NUM_ADCS] = {
530             FSL_IMX6UL_ADC1_ADDR,
531             FSL_IMX6UL_ADC2_ADDR,
532         };
533 
534         snprintf(name, NAME_SIZE, "adc%d", i);
535         create_unimplemented_device(name, FSL_IMX6UL_ADCn_ADDR[i], 0x4000);
536     }
537 
538     /*
539      * LCD
540      */
541     create_unimplemented_device("lcdif", FSL_IMX6UL_LCDIF_ADDR, 0x4000);
542 
543     /*
544      * ROM memory
545      */
546     memory_region_init_rom(&s->rom, NULL, "imx6ul.rom",
547                            FSL_IMX6UL_ROM_SIZE, &error_abort);
548     memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_ROM_ADDR,
549                                 &s->rom);
550 
551     /*
552      * CAAM memory
553      */
554     memory_region_init_rom(&s->caam, NULL, "imx6ul.caam",
555                            FSL_IMX6UL_CAAM_MEM_SIZE, &error_abort);
556     memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_CAAM_MEM_ADDR,
557                                 &s->caam);
558 
559     /*
560      * OCRAM memory
561      */
562     memory_region_init_ram(&s->ocram, NULL, "imx6ul.ocram",
563                            FSL_IMX6UL_OCRAM_MEM_SIZE,
564                            &error_abort);
565     memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_OCRAM_MEM_ADDR,
566                                 &s->ocram);
567 
568     /*
569      * internal OCRAM (128 KB) is aliased over 512 KB
570      */
571     memory_region_init_alias(&s->ocram_alias, NULL, "imx6ul.ocram_alias",
572                              &s->ocram, 0, FSL_IMX6UL_OCRAM_ALIAS_SIZE);
573     memory_region_add_subregion(get_system_memory(),
574                                 FSL_IMX6UL_OCRAM_ALIAS_ADDR, &s->ocram_alias);
575 }
576 
577 static void fsl_imx6ul_class_init(ObjectClass *oc, void *data)
578 {
579     DeviceClass *dc = DEVICE_CLASS(oc);
580 
581     dc->realize = fsl_imx6ul_realize;
582     dc->desc = "i.MX6UL SOC";
583     /* Reason: Uses serial_hds and nd_table in realize() directly */
584     dc->user_creatable = false;
585 }
586 
587 static const TypeInfo fsl_imx6ul_type_info = {
588     .name = TYPE_FSL_IMX6UL,
589     .parent = TYPE_DEVICE,
590     .instance_size = sizeof(FslIMX6ULState),
591     .instance_init = fsl_imx6ul_init,
592     .class_init = fsl_imx6ul_class_init,
593 };
594 
595 static void fsl_imx6ul_register_types(void)
596 {
597     type_register_static(&fsl_imx6ul_type_info);
598 }
599 type_init(fsl_imx6ul_register_types)
600