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