xref: /qemu/hw/arm/fsl-imx6ul.c (revision 513823e7521a09ed7ad1e32e6454bac3b2cbf52d)
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 "system/system.h"
26 #include "qemu/error-report.h"
27 #include "qemu/module.h"
28 #include "target/arm/cpu-qom.h"
29 
30 #define NAME_SIZE 20
31 
32 static void fsl_imx6ul_init(Object *obj)
33 {
34     FslIMX6ULState *s = FSL_IMX6UL(obj);
35     char name[NAME_SIZE];
36     int i;
37 
38     object_initialize_child(obj, "cpu0", &s->cpu,
39                             ARM_CPU_TYPE_NAME("cortex-a7"));
40 
41     /*
42      * A7MPCORE
43      */
44     object_initialize_child(obj, "a7mpcore", &s->a7mpcore,
45                             TYPE_A15MPCORE_PRIV);
46 
47     /*
48      * CCM
49      */
50     object_initialize_child(obj, "ccm", &s->ccm, TYPE_IMX6UL_CCM);
51 
52     /*
53      * SRC
54      */
55     object_initialize_child(obj, "src", &s->src, TYPE_IMX6_SRC);
56 
57     /*
58      * GPCv2
59      */
60     object_initialize_child(obj, "gpcv2", &s->gpcv2, TYPE_IMX_GPCV2);
61 
62     /*
63      * SNVS
64      */
65     object_initialize_child(obj, "snvs", &s->snvs, TYPE_IMX7_SNVS);
66 
67     /*
68      * GPIOs
69      */
70     for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
71         snprintf(name, NAME_SIZE, "gpio%d", i);
72         object_initialize_child(obj, name, &s->gpio[i], TYPE_IMX_GPIO);
73     }
74 
75     /*
76      * GPTs
77      */
78     for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
79         snprintf(name, NAME_SIZE, "gpt%d", i);
80         object_initialize_child(obj, name, &s->gpt[i], TYPE_IMX6UL_GPT);
81     }
82 
83     /*
84      * EPITs
85      */
86     for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
87         snprintf(name, NAME_SIZE, "epit%d", i + 1);
88         object_initialize_child(obj, name, &s->epit[i], TYPE_IMX_EPIT);
89     }
90 
91     /*
92      * eCSPIs
93      */
94     for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) {
95         snprintf(name, NAME_SIZE, "spi%d", i + 1);
96         object_initialize_child(obj, name, &s->spi[i], TYPE_IMX_SPI);
97     }
98 
99     /*
100      * I2Cs
101      */
102     for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) {
103         snprintf(name, NAME_SIZE, "i2c%d", i + 1);
104         object_initialize_child(obj, name, &s->i2c[i], TYPE_IMX_I2C);
105     }
106 
107     /*
108      * UARTs
109      */
110     for (i = 0; i < FSL_IMX6UL_NUM_UARTS; i++) {
111         snprintf(name, NAME_SIZE, "uart%d", i);
112         object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL);
113     }
114 
115     /*
116      * Ethernets
117      */
118     for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
119         snprintf(name, NAME_SIZE, "eth%d", i);
120         object_initialize_child(obj, name, &s->eth[i], TYPE_IMX_ENET);
121     }
122 
123     /*
124      * USB PHYs
125      */
126     for (i = 0; i < FSL_IMX6UL_NUM_USB_PHYS; i++) {
127         snprintf(name, NAME_SIZE, "usbphy%d", i);
128         object_initialize_child(obj, name, &s->usbphy[i], TYPE_IMX_USBPHY);
129     }
130 
131     /*
132      * USBs
133      */
134     for (i = 0; i < FSL_IMX6UL_NUM_USBS; i++) {
135         snprintf(name, NAME_SIZE, "usb%d", i);
136         object_initialize_child(obj, name, &s->usb[i], TYPE_CHIPIDEA);
137     }
138 
139     /*
140      * SDHCIs
141      */
142     for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
143         snprintf(name, NAME_SIZE, "usdhc%d", i);
144         object_initialize_child(obj, name, &s->usdhc[i], TYPE_IMX_USDHC);
145     }
146 
147     /*
148      * Watchdogs
149      */
150     for (i = 0; i < FSL_IMX6UL_NUM_WDTS; i++) {
151         snprintf(name, NAME_SIZE, "wdt%d", i);
152         object_initialize_child(obj, name, &s->wdt[i], TYPE_IMX2_WDT);
153     }
154 }
155 
156 static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
157 {
158     MachineState *ms = MACHINE(qdev_get_machine());
159     FslIMX6ULState *s = FSL_IMX6UL(dev);
160     DeviceState *mpcore = DEVICE(&s->a7mpcore);
161     int i;
162     char name[NAME_SIZE];
163     DeviceState *gic;
164     SysBusDevice *gicsbd;
165     DeviceState *cpu;
166 
167     if (ms->smp.cpus > 1) {
168         error_setg(errp, "%s: Only a single CPU is supported (%d requested)",
169                    TYPE_FSL_IMX6UL, ms->smp.cpus);
170         return;
171     }
172 
173     qdev_realize(DEVICE(&s->cpu), NULL, &error_abort);
174 
175     /*
176      * A7MPCORE
177      */
178     object_property_set_int(OBJECT(mpcore), "num-cpu", 1, &error_abort);
179     object_property_set_int(OBJECT(mpcore), "num-irq",
180                             FSL_IMX6UL_MAX_IRQ + GIC_INTERNAL, &error_abort);
181     sysbus_realize(SYS_BUS_DEVICE(mpcore), &error_abort);
182     sysbus_mmio_map(SYS_BUS_DEVICE(mpcore), 0, FSL_IMX6UL_A7MPCORE_ADDR);
183 
184     gic = mpcore;
185     gicsbd = SYS_BUS_DEVICE(gic);
186     cpu = DEVICE(&s->cpu);
187     sysbus_connect_irq(gicsbd, 0, qdev_get_gpio_in(cpu, ARM_CPU_IRQ));
188     sysbus_connect_irq(gicsbd, 1, qdev_get_gpio_in(cpu, ARM_CPU_FIQ));
189     sysbus_connect_irq(gicsbd, 2, qdev_get_gpio_in(cpu, ARM_CPU_VIRQ));
190     sysbus_connect_irq(gicsbd, 3, qdev_get_gpio_in(cpu, ARM_CPU_VFIQ));
191 
192     /*
193      * A7MPCORE DAP
194      */
195     create_unimplemented_device("a7mpcore-dap", FSL_IMX6UL_A7MPCORE_DAP_ADDR,
196                                 FSL_IMX6UL_A7MPCORE_DAP_SIZE);
197 
198     /*
199      * MMDC
200      */
201     create_unimplemented_device("a7mpcore-mmdc", FSL_IMX6UL_MMDC_CFG_ADDR,
202                                 FSL_IMX6UL_MMDC_CFG_SIZE);
203 
204     /*
205      * OCOTP
206      */
207     create_unimplemented_device("a7mpcore-ocotp", FSL_IMX6UL_OCOTP_CTRL_ADDR,
208                                 FSL_IMX6UL_OCOTP_CTRL_SIZE);
209 
210     /*
211      * QSPI
212      */
213     create_unimplemented_device("a7mpcore-qspi", FSL_IMX6UL_QSPI_ADDR,
214                                 FSL_IMX6UL_QSPI_SIZE);
215 
216     /*
217      * CAAM
218      */
219     create_unimplemented_device("a7mpcore-qspi", FSL_IMX6UL_CAAM_ADDR,
220                                 FSL_IMX6UL_CAAM_SIZE);
221 
222     /*
223      * USBMISC
224      */
225     create_unimplemented_device("a7mpcore-usbmisc", FSL_IMX6UL_USBO2_USBMISC_ADDR,
226                                 FSL_IMX6UL_USBO2_USBMISC_SIZE);
227 
228     /*
229      * GPTs
230      */
231     for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
232         static const hwaddr FSL_IMX6UL_GPTn_ADDR[FSL_IMX6UL_NUM_GPTS] = {
233             FSL_IMX6UL_GPT1_ADDR,
234             FSL_IMX6UL_GPT2_ADDR,
235         };
236 
237         static const int FSL_IMX6UL_GPTn_IRQ[FSL_IMX6UL_NUM_GPTS] = {
238             FSL_IMX6UL_GPT1_IRQ,
239             FSL_IMX6UL_GPT2_IRQ,
240         };
241 
242         s->gpt[i].ccm = IMX_CCM(&s->ccm);
243         sysbus_realize(SYS_BUS_DEVICE(&s->gpt[i]), &error_abort);
244 
245         sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0,
246                         FSL_IMX6UL_GPTn_ADDR[i]);
247 
248         sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0,
249                            qdev_get_gpio_in(gic, FSL_IMX6UL_GPTn_IRQ[i]));
250     }
251 
252     /*
253      * EPITs
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         sysbus_realize(SYS_BUS_DEVICE(&s->epit[i]), &error_abort);
268 
269         sysbus_mmio_map(SYS_BUS_DEVICE(&s->epit[i]), 0,
270                         FSL_IMX6UL_EPITn_ADDR[i]);
271 
272         sysbus_connect_irq(SYS_BUS_DEVICE(&s->epit[i]), 0,
273                            qdev_get_gpio_in(gic, FSL_IMX6UL_EPITn_IRQ[i]));
274     }
275 
276     /*
277      * GPIOs
278      */
279     for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
280         static const hwaddr FSL_IMX6UL_GPIOn_ADDR[FSL_IMX6UL_NUM_GPIOS] = {
281             FSL_IMX6UL_GPIO1_ADDR,
282             FSL_IMX6UL_GPIO2_ADDR,
283             FSL_IMX6UL_GPIO3_ADDR,
284             FSL_IMX6UL_GPIO4_ADDR,
285             FSL_IMX6UL_GPIO5_ADDR,
286         };
287 
288         static const int FSL_IMX6UL_GPIOn_LOW_IRQ[FSL_IMX6UL_NUM_GPIOS] = {
289             FSL_IMX6UL_GPIO1_LOW_IRQ,
290             FSL_IMX6UL_GPIO2_LOW_IRQ,
291             FSL_IMX6UL_GPIO3_LOW_IRQ,
292             FSL_IMX6UL_GPIO4_LOW_IRQ,
293             FSL_IMX6UL_GPIO5_LOW_IRQ,
294         };
295 
296         static const int FSL_IMX6UL_GPIOn_HIGH_IRQ[FSL_IMX6UL_NUM_GPIOS] = {
297             FSL_IMX6UL_GPIO1_HIGH_IRQ,
298             FSL_IMX6UL_GPIO2_HIGH_IRQ,
299             FSL_IMX6UL_GPIO3_HIGH_IRQ,
300             FSL_IMX6UL_GPIO4_HIGH_IRQ,
301             FSL_IMX6UL_GPIO5_HIGH_IRQ,
302         };
303 
304         sysbus_realize(SYS_BUS_DEVICE(&s->gpio[i]), &error_abort);
305 
306         sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0,
307                         FSL_IMX6UL_GPIOn_ADDR[i]);
308 
309         sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0,
310                            qdev_get_gpio_in(gic, FSL_IMX6UL_GPIOn_LOW_IRQ[i]));
311 
312         sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 1,
313                            qdev_get_gpio_in(gic, FSL_IMX6UL_GPIOn_HIGH_IRQ[i]));
314     }
315 
316     /*
317      * IOMUXC
318      */
319     create_unimplemented_device("iomuxc", FSL_IMX6UL_IOMUXC_ADDR,
320                                 FSL_IMX6UL_IOMUXC_SIZE);
321     create_unimplemented_device("iomuxc_gpr", FSL_IMX6UL_IOMUXC_GPR_ADDR,
322                                 FSL_IMX6UL_IOMUXC_GPR_SIZE);
323 
324     /*
325      * CCM
326      */
327     sysbus_realize(SYS_BUS_DEVICE(&s->ccm), &error_abort);
328     sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX6UL_CCM_ADDR);
329 
330     /*
331      * SRC
332      */
333     sysbus_realize(SYS_BUS_DEVICE(&s->src), &error_abort);
334     sysbus_mmio_map(SYS_BUS_DEVICE(&s->src), 0, FSL_IMX6UL_SRC_ADDR);
335 
336     /*
337      * GPCv2
338      */
339     sysbus_realize(SYS_BUS_DEVICE(&s->gpcv2), &error_abort);
340     sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpcv2), 0, FSL_IMX6UL_GPC_ADDR);
341 
342     /*
343      * ECSPIs
344      */
345     for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) {
346         static const hwaddr FSL_IMX6UL_SPIn_ADDR[FSL_IMX6UL_NUM_ECSPIS] = {
347             FSL_IMX6UL_ECSPI1_ADDR,
348             FSL_IMX6UL_ECSPI2_ADDR,
349             FSL_IMX6UL_ECSPI3_ADDR,
350             FSL_IMX6UL_ECSPI4_ADDR,
351         };
352 
353         static const int FSL_IMX6UL_SPIn_IRQ[FSL_IMX6UL_NUM_ECSPIS] = {
354             FSL_IMX6UL_ECSPI1_IRQ,
355             FSL_IMX6UL_ECSPI2_IRQ,
356             FSL_IMX6UL_ECSPI3_IRQ,
357             FSL_IMX6UL_ECSPI4_IRQ,
358         };
359 
360         /* Initialize the SPI */
361         sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), &error_abort);
362 
363         sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0,
364                         FSL_IMX6UL_SPIn_ADDR[i]);
365 
366         sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0,
367                            qdev_get_gpio_in(gic, FSL_IMX6UL_SPIn_IRQ[i]));
368     }
369 
370     /*
371      * I2Cs
372      */
373     for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) {
374         static const hwaddr FSL_IMX6UL_I2Cn_ADDR[FSL_IMX6UL_NUM_I2CS] = {
375             FSL_IMX6UL_I2C1_ADDR,
376             FSL_IMX6UL_I2C2_ADDR,
377             FSL_IMX6UL_I2C3_ADDR,
378             FSL_IMX6UL_I2C4_ADDR,
379         };
380 
381         static const int FSL_IMX6UL_I2Cn_IRQ[FSL_IMX6UL_NUM_I2CS] = {
382             FSL_IMX6UL_I2C1_IRQ,
383             FSL_IMX6UL_I2C2_IRQ,
384             FSL_IMX6UL_I2C3_IRQ,
385             FSL_IMX6UL_I2C4_IRQ,
386         };
387 
388         sysbus_realize(SYS_BUS_DEVICE(&s->i2c[i]), &error_abort);
389         sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, FSL_IMX6UL_I2Cn_ADDR[i]);
390 
391         sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
392                            qdev_get_gpio_in(gic, FSL_IMX6UL_I2Cn_IRQ[i]));
393     }
394 
395     /*
396      * UARTs
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         sysbus_realize(SYS_BUS_DEVICE(&s->uart[i]), &error_abort);
424 
425         sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0,
426                         FSL_IMX6UL_UARTn_ADDR[i]);
427 
428         sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0,
429                            qdev_get_gpio_in(gic, FSL_IMX6UL_UARTn_IRQ[i]));
430     }
431 
432     /*
433      * Ethernets
434      *
435      * We must use two loops since phy_connected affects the other interface
436      * and we have to set all properties before calling sysbus_realize().
437      */
438     for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
439         object_property_set_bool(OBJECT(&s->eth[i]), "phy-connected",
440                                  s->phy_connected[i], &error_abort);
441         /*
442          * If the MDIO bus on this controller is not connected, assume the
443          * other controller provides support for it.
444          */
445         if (!s->phy_connected[i]) {
446             object_property_set_link(OBJECT(&s->eth[1 - i]), "phy-consumer",
447                                      OBJECT(&s->eth[i]), &error_abort);
448         }
449     }
450 
451     for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
452         static const hwaddr FSL_IMX6UL_ENETn_ADDR[FSL_IMX6UL_NUM_ETHS] = {
453             FSL_IMX6UL_ENET1_ADDR,
454             FSL_IMX6UL_ENET2_ADDR,
455         };
456 
457         static const int FSL_IMX6UL_ENETn_IRQ[FSL_IMX6UL_NUM_ETHS] = {
458             FSL_IMX6UL_ENET1_IRQ,
459             FSL_IMX6UL_ENET2_IRQ,
460         };
461 
462         static const int FSL_IMX6UL_ENETn_TIMER_IRQ[FSL_IMX6UL_NUM_ETHS] = {
463             FSL_IMX6UL_ENET1_TIMER_IRQ,
464             FSL_IMX6UL_ENET2_TIMER_IRQ,
465         };
466 
467         object_property_set_uint(OBJECT(&s->eth[i]), "phy-num",
468                                  s->phy_num[i], &error_abort);
469         object_property_set_uint(OBJECT(&s->eth[i]), "tx-ring-num",
470                                  FSL_IMX6UL_ETH_NUM_TX_RINGS, &error_abort);
471         qemu_configure_nic_device(DEVICE(&s->eth[i]), true, NULL);
472         sysbus_realize(SYS_BUS_DEVICE(&s->eth[i]), &error_abort);
473 
474         sysbus_mmio_map(SYS_BUS_DEVICE(&s->eth[i]), 0,
475                         FSL_IMX6UL_ENETn_ADDR[i]);
476 
477         sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 0,
478                            qdev_get_gpio_in(gic, FSL_IMX6UL_ENETn_IRQ[i]));
479 
480         sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 1,
481                            qdev_get_gpio_in(gic, FSL_IMX6UL_ENETn_TIMER_IRQ[i]));
482     }
483 
484     /*
485      * USB PHYs
486      */
487     for (i = 0; i < FSL_IMX6UL_NUM_USB_PHYS; i++) {
488         static const hwaddr
489                      FSL_IMX6UL_USB_PHYn_ADDR[FSL_IMX6UL_NUM_USB_PHYS] = {
490             FSL_IMX6UL_USBPHY1_ADDR,
491             FSL_IMX6UL_USBPHY2_ADDR,
492         };
493 
494         sysbus_realize(SYS_BUS_DEVICE(&s->usbphy[i]), &error_abort);
495         sysbus_mmio_map(SYS_BUS_DEVICE(&s->usbphy[i]), 0,
496                         FSL_IMX6UL_USB_PHYn_ADDR[i]);
497     }
498 
499     /*
500      * USBs
501      */
502     for (i = 0; i < FSL_IMX6UL_NUM_USBS; i++) {
503         static const hwaddr FSL_IMX6UL_USB02_USBn_ADDR[FSL_IMX6UL_NUM_USBS] = {
504             FSL_IMX6UL_USBO2_USB1_ADDR,
505             FSL_IMX6UL_USBO2_USB2_ADDR,
506         };
507 
508         static const int FSL_IMX6UL_USBn_IRQ[] = {
509             FSL_IMX6UL_USB1_IRQ,
510             FSL_IMX6UL_USB2_IRQ,
511         };
512 
513         sysbus_realize(SYS_BUS_DEVICE(&s->usb[i]), &error_abort);
514         sysbus_mmio_map(SYS_BUS_DEVICE(&s->usb[i]), 0,
515                         FSL_IMX6UL_USB02_USBn_ADDR[i]);
516         sysbus_connect_irq(SYS_BUS_DEVICE(&s->usb[i]), 0,
517                            qdev_get_gpio_in(gic, FSL_IMX6UL_USBn_IRQ[i]));
518     }
519 
520     /*
521      * USDHCs
522      */
523     for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
524         static const hwaddr FSL_IMX6UL_USDHCn_ADDR[FSL_IMX6UL_NUM_USDHCS] = {
525             FSL_IMX6UL_USDHC1_ADDR,
526             FSL_IMX6UL_USDHC2_ADDR,
527         };
528 
529         static const int FSL_IMX6UL_USDHCn_IRQ[FSL_IMX6UL_NUM_USDHCS] = {
530             FSL_IMX6UL_USDHC1_IRQ,
531             FSL_IMX6UL_USDHC2_IRQ,
532         };
533 
534         object_property_set_uint(OBJECT(&s->usdhc[i]), "vendor",
535                                  SDHCI_VENDOR_IMX, &error_abort);
536         sysbus_realize(SYS_BUS_DEVICE(&s->usdhc[i]), &error_abort);
537 
538         sysbus_mmio_map(SYS_BUS_DEVICE(&s->usdhc[i]), 0,
539                         FSL_IMX6UL_USDHCn_ADDR[i]);
540 
541         sysbus_connect_irq(SYS_BUS_DEVICE(&s->usdhc[i]), 0,
542                            qdev_get_gpio_in(gic, FSL_IMX6UL_USDHCn_IRQ[i]));
543     }
544 
545     /*
546      * SNVS
547      */
548     sysbus_realize(SYS_BUS_DEVICE(&s->snvs), &error_abort);
549     sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0, FSL_IMX6UL_SNVS_HP_ADDR);
550 
551     /*
552      * Watchdogs
553      */
554     for (i = 0; i < FSL_IMX6UL_NUM_WDTS; i++) {
555         static const hwaddr FSL_IMX6UL_WDOGn_ADDR[FSL_IMX6UL_NUM_WDTS] = {
556             FSL_IMX6UL_WDOG1_ADDR,
557             FSL_IMX6UL_WDOG2_ADDR,
558             FSL_IMX6UL_WDOG3_ADDR,
559         };
560 
561         static const int FSL_IMX6UL_WDOGn_IRQ[FSL_IMX6UL_NUM_WDTS] = {
562             FSL_IMX6UL_WDOG1_IRQ,
563             FSL_IMX6UL_WDOG2_IRQ,
564             FSL_IMX6UL_WDOG3_IRQ,
565         };
566 
567         object_property_set_bool(OBJECT(&s->wdt[i]), "pretimeout-support",
568                                  true, &error_abort);
569         sysbus_realize(SYS_BUS_DEVICE(&s->wdt[i]), &error_abort);
570 
571         sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0,
572                         FSL_IMX6UL_WDOGn_ADDR[i]);
573         sysbus_connect_irq(SYS_BUS_DEVICE(&s->wdt[i]), 0,
574                            qdev_get_gpio_in(gic, FSL_IMX6UL_WDOGn_IRQ[i]));
575     }
576 
577     /*
578      * SDMA
579      */
580     create_unimplemented_device("sdma", FSL_IMX6UL_SDMA_ADDR,
581                                 FSL_IMX6UL_SDMA_SIZE);
582 
583     /*
584      * SAIs (Audio SSI (Synchronous Serial Interface))
585      */
586     for (i = 0; i < FSL_IMX6UL_NUM_SAIS; i++) {
587         static const hwaddr FSL_IMX6UL_SAIn_ADDR[FSL_IMX6UL_NUM_SAIS] = {
588             FSL_IMX6UL_SAI1_ADDR,
589             FSL_IMX6UL_SAI2_ADDR,
590             FSL_IMX6UL_SAI3_ADDR,
591         };
592 
593         snprintf(name, NAME_SIZE, "sai%d", i);
594         create_unimplemented_device(name, FSL_IMX6UL_SAIn_ADDR[i],
595                                     FSL_IMX6UL_SAIn_SIZE);
596     }
597 
598     /*
599      * PWMs
600      */
601     for (i = 0; i < FSL_IMX6UL_NUM_PWMS; i++) {
602         static const hwaddr FSL_IMX6UL_PWMn_ADDR[FSL_IMX6UL_NUM_PWMS] = {
603             FSL_IMX6UL_PWM1_ADDR,
604             FSL_IMX6UL_PWM2_ADDR,
605             FSL_IMX6UL_PWM3_ADDR,
606             FSL_IMX6UL_PWM4_ADDR,
607             FSL_IMX6UL_PWM5_ADDR,
608             FSL_IMX6UL_PWM6_ADDR,
609             FSL_IMX6UL_PWM7_ADDR,
610             FSL_IMX6UL_PWM8_ADDR,
611         };
612 
613         snprintf(name, NAME_SIZE, "pwm%d", i);
614         create_unimplemented_device(name, FSL_IMX6UL_PWMn_ADDR[i],
615                                     FSL_IMX6UL_PWMn_SIZE);
616     }
617 
618     /*
619      * Audio ASRC (asynchronous sample rate converter)
620      */
621     create_unimplemented_device("asrc", FSL_IMX6UL_ASRC_ADDR,
622                                 FSL_IMX6UL_ASRC_SIZE);
623 
624     /*
625      * CANs
626      */
627     for (i = 0; i < FSL_IMX6UL_NUM_CANS; i++) {
628         static const hwaddr FSL_IMX6UL_CANn_ADDR[FSL_IMX6UL_NUM_CANS] = {
629             FSL_IMX6UL_CAN1_ADDR,
630             FSL_IMX6UL_CAN2_ADDR,
631         };
632 
633         snprintf(name, NAME_SIZE, "can%d", i);
634         create_unimplemented_device(name, FSL_IMX6UL_CANn_ADDR[i],
635                                     FSL_IMX6UL_CANn_SIZE);
636     }
637 
638     /*
639      * APHB_DMA
640      */
641     create_unimplemented_device("aphb_dma", FSL_IMX6UL_APBH_DMA_ADDR,
642                                 FSL_IMX6UL_APBH_DMA_SIZE);
643 
644     /*
645      * ADCs
646      */
647     for (i = 0; i < FSL_IMX6UL_NUM_ADCS; i++) {
648         static const hwaddr FSL_IMX6UL_ADCn_ADDR[FSL_IMX6UL_NUM_ADCS] = {
649             FSL_IMX6UL_ADC1_ADDR,
650             FSL_IMX6UL_ADC2_ADDR,
651         };
652 
653         snprintf(name, NAME_SIZE, "adc%d", i);
654         create_unimplemented_device(name, FSL_IMX6UL_ADCn_ADDR[i],
655                                     FSL_IMX6UL_ADCn_SIZE);
656     }
657 
658     /*
659      * LCD
660      */
661     create_unimplemented_device("lcdif", FSL_IMX6UL_LCDIF_ADDR,
662                                 FSL_IMX6UL_LCDIF_SIZE);
663 
664     /*
665      * CSU
666      */
667     create_unimplemented_device("csu", FSL_IMX6UL_CSU_ADDR,
668                                 FSL_IMX6UL_CSU_SIZE);
669 
670     /*
671      * TZASC
672      */
673     create_unimplemented_device("tzasc", FSL_IMX6UL_TZASC_ADDR,
674                                 FSL_IMX6UL_TZASC_SIZE);
675 
676     /*
677      * ROM memory
678      */
679     memory_region_init_rom(&s->rom, OBJECT(dev), "imx6ul.rom",
680                            FSL_IMX6UL_ROM_SIZE, &error_abort);
681     memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_ROM_ADDR,
682                                 &s->rom);
683 
684     /*
685      * CAAM memory
686      */
687     memory_region_init_rom(&s->caam, OBJECT(dev), "imx6ul.caam",
688                            FSL_IMX6UL_CAAM_MEM_SIZE, &error_abort);
689     memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_CAAM_MEM_ADDR,
690                                 &s->caam);
691 
692     /*
693      * OCRAM memory
694      */
695     memory_region_init_ram(&s->ocram, NULL, "imx6ul.ocram",
696                            FSL_IMX6UL_OCRAM_MEM_SIZE,
697                            &error_abort);
698     memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_OCRAM_MEM_ADDR,
699                                 &s->ocram);
700 
701     /*
702      * internal OCRAM (128 KB) is aliased over 512 KB
703      */
704     memory_region_init_alias(&s->ocram_alias, OBJECT(dev),
705                              "imx6ul.ocram_alias", &s->ocram, 0,
706                              FSL_IMX6UL_OCRAM_ALIAS_SIZE);
707     memory_region_add_subregion(get_system_memory(),
708                                 FSL_IMX6UL_OCRAM_ALIAS_ADDR, &s->ocram_alias);
709 }
710 
711 static const Property fsl_imx6ul_properties[] = {
712     DEFINE_PROP_UINT32("fec1-phy-num", FslIMX6ULState, phy_num[0], 0),
713     DEFINE_PROP_UINT32("fec2-phy-num", FslIMX6ULState, phy_num[1], 1),
714     DEFINE_PROP_BOOL("fec1-phy-connected", FslIMX6ULState, phy_connected[0],
715                      true),
716     DEFINE_PROP_BOOL("fec2-phy-connected", FslIMX6ULState, phy_connected[1],
717                      true),
718 };
719 
720 static void fsl_imx6ul_class_init(ObjectClass *oc, void *data)
721 {
722     DeviceClass *dc = DEVICE_CLASS(oc);
723 
724     device_class_set_props(dc, fsl_imx6ul_properties);
725     dc->realize = fsl_imx6ul_realize;
726     dc->desc = "i.MX6UL SOC";
727     /* Reason: Uses serial_hds and nd_table in realize() directly */
728     dc->user_creatable = false;
729 }
730 
731 static const TypeInfo fsl_imx6ul_type_info = {
732     .name = TYPE_FSL_IMX6UL,
733     .parent = TYPE_DEVICE,
734     .instance_size = sizeof(FslIMX6ULState),
735     .instance_init = fsl_imx6ul_init,
736     .class_init = fsl_imx6ul_class_init,
737 };
738 
739 static void fsl_imx6ul_register_types(void)
740 {
741     type_register_static(&fsl_imx6ul_type_info);
742 }
743 type_init(fsl_imx6ul_register_types)
744