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