xref: /openbmc/qemu/hw/arm/fsl-imx6ul.c (revision 861bbc88)
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 #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     int i;
161     char name[NAME_SIZE];
162     SysBusDevice *sbd;
163     DeviceState *d;
164 
165     if (ms->smp.cpus > 1) {
166         error_setg(errp, "%s: Only a single CPU is supported (%d requested)",
167                    TYPE_FSL_IMX6UL, ms->smp.cpus);
168         return;
169     }
170 
171     qdev_realize(DEVICE(&s->cpu), NULL, &error_abort);
172 
173     /*
174      * A7MPCORE
175      */
176     object_property_set_int(OBJECT(&s->a7mpcore), "num-cpu", 1, &error_abort);
177     object_property_set_int(OBJECT(&s->a7mpcore), "num-irq",
178                             FSL_IMX6UL_MAX_IRQ + GIC_INTERNAL, &error_abort);
179     sysbus_realize(SYS_BUS_DEVICE(&s->a7mpcore), &error_abort);
180     sysbus_mmio_map(SYS_BUS_DEVICE(&s->a7mpcore), 0, FSL_IMX6UL_A7MPCORE_ADDR);
181 
182     sbd = SYS_BUS_DEVICE(&s->a7mpcore);
183     d = DEVICE(&s->cpu);
184 
185     sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(d, ARM_CPU_IRQ));
186     sysbus_connect_irq(sbd, 1, qdev_get_gpio_in(d, ARM_CPU_FIQ));
187     sysbus_connect_irq(sbd, 2, qdev_get_gpio_in(d, ARM_CPU_VIRQ));
188     sysbus_connect_irq(sbd, 3, qdev_get_gpio_in(d, ARM_CPU_VFIQ));
189 
190     /*
191      * A7MPCORE DAP
192      */
193     create_unimplemented_device("a7mpcore-dap", FSL_IMX6UL_A7MPCORE_DAP_ADDR,
194                                 FSL_IMX6UL_A7MPCORE_DAP_SIZE);
195 
196     /*
197      * MMDC
198      */
199     create_unimplemented_device("a7mpcore-mmdc", FSL_IMX6UL_MMDC_CFG_ADDR,
200                                 FSL_IMX6UL_MMDC_CFG_SIZE);
201 
202     /*
203      * OCOTP
204      */
205     create_unimplemented_device("a7mpcore-ocotp", FSL_IMX6UL_OCOTP_CTRL_ADDR,
206                                 FSL_IMX6UL_OCOTP_CTRL_SIZE);
207 
208     /*
209      * QSPI
210      */
211     create_unimplemented_device("a7mpcore-qspi", FSL_IMX6UL_QSPI_ADDR,
212                                 FSL_IMX6UL_QSPI_SIZE);
213 
214     /*
215      * CAAM
216      */
217     create_unimplemented_device("a7mpcore-qspi", FSL_IMX6UL_CAAM_ADDR,
218                                 FSL_IMX6UL_CAAM_SIZE);
219 
220     /*
221      * USBMISC
222      */
223     create_unimplemented_device("a7mpcore-usbmisc", FSL_IMX6UL_USBO2_USBMISC_ADDR,
224                                 FSL_IMX6UL_USBO2_USBMISC_SIZE);
225 
226     /*
227      * GPTs
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         sysbus_realize(SYS_BUS_DEVICE(&s->gpt[i]), &error_abort);
242 
243         sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0,
244                         FSL_IMX6UL_GPTn_ADDR[i]);
245 
246         sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0,
247                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
248                                             FSL_IMX6UL_GPTn_IRQ[i]));
249     }
250 
251     /*
252      * EPITs
253      */
254     for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
255         static const hwaddr FSL_IMX6UL_EPITn_ADDR[FSL_IMX6UL_NUM_EPITS] = {
256             FSL_IMX6UL_EPIT1_ADDR,
257             FSL_IMX6UL_EPIT2_ADDR,
258         };
259 
260         static const int FSL_IMX6UL_EPITn_IRQ[FSL_IMX6UL_NUM_EPITS] = {
261             FSL_IMX6UL_EPIT1_IRQ,
262             FSL_IMX6UL_EPIT2_IRQ,
263         };
264 
265         s->epit[i].ccm = IMX_CCM(&s->ccm);
266         sysbus_realize(SYS_BUS_DEVICE(&s->epit[i]), &error_abort);
267 
268         sysbus_mmio_map(SYS_BUS_DEVICE(&s->epit[i]), 0,
269                         FSL_IMX6UL_EPITn_ADDR[i]);
270 
271         sysbus_connect_irq(SYS_BUS_DEVICE(&s->epit[i]), 0,
272                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
273                                             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(DEVICE(&s->a7mpcore),
311                                             FSL_IMX6UL_GPIOn_LOW_IRQ[i]));
312 
313         sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 1,
314                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
315                                             FSL_IMX6UL_GPIOn_HIGH_IRQ[i]));
316     }
317 
318     /*
319      * IOMUXC
320      */
321     create_unimplemented_device("iomuxc", FSL_IMX6UL_IOMUXC_ADDR,
322                                 FSL_IMX6UL_IOMUXC_SIZE);
323     create_unimplemented_device("iomuxc_gpr", FSL_IMX6UL_IOMUXC_GPR_ADDR,
324                                 FSL_IMX6UL_IOMUXC_GPR_SIZE);
325 
326     /*
327      * CCM
328      */
329     sysbus_realize(SYS_BUS_DEVICE(&s->ccm), &error_abort);
330     sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX6UL_CCM_ADDR);
331 
332     /*
333      * SRC
334      */
335     sysbus_realize(SYS_BUS_DEVICE(&s->src), &error_abort);
336     sysbus_mmio_map(SYS_BUS_DEVICE(&s->src), 0, FSL_IMX6UL_SRC_ADDR);
337 
338     /*
339      * GPCv2
340      */
341     sysbus_realize(SYS_BUS_DEVICE(&s->gpcv2), &error_abort);
342     sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpcv2), 0, FSL_IMX6UL_GPC_ADDR);
343 
344     /*
345      * ECSPIs
346      */
347     for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) {
348         static const hwaddr FSL_IMX6UL_SPIn_ADDR[FSL_IMX6UL_NUM_ECSPIS] = {
349             FSL_IMX6UL_ECSPI1_ADDR,
350             FSL_IMX6UL_ECSPI2_ADDR,
351             FSL_IMX6UL_ECSPI3_ADDR,
352             FSL_IMX6UL_ECSPI4_ADDR,
353         };
354 
355         static const int FSL_IMX6UL_SPIn_IRQ[FSL_IMX6UL_NUM_ECSPIS] = {
356             FSL_IMX6UL_ECSPI1_IRQ,
357             FSL_IMX6UL_ECSPI2_IRQ,
358             FSL_IMX6UL_ECSPI3_IRQ,
359             FSL_IMX6UL_ECSPI4_IRQ,
360         };
361 
362         /* Initialize the SPI */
363         sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), &error_abort);
364 
365         sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0,
366                         FSL_IMX6UL_SPIn_ADDR[i]);
367 
368         sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0,
369                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
370                                             FSL_IMX6UL_SPIn_IRQ[i]));
371     }
372 
373     /*
374      * I2Cs
375      */
376     for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) {
377         static const hwaddr FSL_IMX6UL_I2Cn_ADDR[FSL_IMX6UL_NUM_I2CS] = {
378             FSL_IMX6UL_I2C1_ADDR,
379             FSL_IMX6UL_I2C2_ADDR,
380             FSL_IMX6UL_I2C3_ADDR,
381             FSL_IMX6UL_I2C4_ADDR,
382         };
383 
384         static const int FSL_IMX6UL_I2Cn_IRQ[FSL_IMX6UL_NUM_I2CS] = {
385             FSL_IMX6UL_I2C1_IRQ,
386             FSL_IMX6UL_I2C2_IRQ,
387             FSL_IMX6UL_I2C3_IRQ,
388             FSL_IMX6UL_I2C4_IRQ,
389         };
390 
391         sysbus_realize(SYS_BUS_DEVICE(&s->i2c[i]), &error_abort);
392         sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, FSL_IMX6UL_I2Cn_ADDR[i]);
393 
394         sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
395                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
396                                             FSL_IMX6UL_I2Cn_IRQ[i]));
397     }
398 
399     /*
400      * UARTs
401      */
402     for (i = 0; i < FSL_IMX6UL_NUM_UARTS; i++) {
403         static const hwaddr FSL_IMX6UL_UARTn_ADDR[FSL_IMX6UL_NUM_UARTS] = {
404             FSL_IMX6UL_UART1_ADDR,
405             FSL_IMX6UL_UART2_ADDR,
406             FSL_IMX6UL_UART3_ADDR,
407             FSL_IMX6UL_UART4_ADDR,
408             FSL_IMX6UL_UART5_ADDR,
409             FSL_IMX6UL_UART6_ADDR,
410             FSL_IMX6UL_UART7_ADDR,
411             FSL_IMX6UL_UART8_ADDR,
412         };
413 
414         static const int FSL_IMX6UL_UARTn_IRQ[FSL_IMX6UL_NUM_UARTS] = {
415             FSL_IMX6UL_UART1_IRQ,
416             FSL_IMX6UL_UART2_IRQ,
417             FSL_IMX6UL_UART3_IRQ,
418             FSL_IMX6UL_UART4_IRQ,
419             FSL_IMX6UL_UART5_IRQ,
420             FSL_IMX6UL_UART6_IRQ,
421             FSL_IMX6UL_UART7_IRQ,
422             FSL_IMX6UL_UART8_IRQ,
423         };
424 
425         qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", serial_hd(i));
426 
427         sysbus_realize(SYS_BUS_DEVICE(&s->uart[i]), &error_abort);
428 
429         sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0,
430                         FSL_IMX6UL_UARTn_ADDR[i]);
431 
432         sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0,
433                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
434                                             FSL_IMX6UL_UARTn_IRQ[i]));
435     }
436 
437     /*
438      * Ethernets
439      *
440      * We must use two loops since phy_connected affects the other interface
441      * and we have to set all properties before calling sysbus_realize().
442      */
443     for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
444         object_property_set_bool(OBJECT(&s->eth[i]), "phy-connected",
445                                  s->phy_connected[i], &error_abort);
446         /*
447          * If the MDIO bus on this controller is not connected, assume the
448          * other controller provides support for it.
449          */
450         if (!s->phy_connected[i]) {
451             object_property_set_link(OBJECT(&s->eth[1 - i]), "phy-consumer",
452                                      OBJECT(&s->eth[i]), &error_abort);
453         }
454     }
455 
456     for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
457         static const hwaddr FSL_IMX6UL_ENETn_ADDR[FSL_IMX6UL_NUM_ETHS] = {
458             FSL_IMX6UL_ENET1_ADDR,
459             FSL_IMX6UL_ENET2_ADDR,
460         };
461 
462         static const int FSL_IMX6UL_ENETn_IRQ[FSL_IMX6UL_NUM_ETHS] = {
463             FSL_IMX6UL_ENET1_IRQ,
464             FSL_IMX6UL_ENET2_IRQ,
465         };
466 
467         static const int FSL_IMX6UL_ENETn_TIMER_IRQ[FSL_IMX6UL_NUM_ETHS] = {
468             FSL_IMX6UL_ENET1_TIMER_IRQ,
469             FSL_IMX6UL_ENET2_TIMER_IRQ,
470         };
471 
472         object_property_set_uint(OBJECT(&s->eth[i]), "phy-num",
473                                  s->phy_num[i], &error_abort);
474         object_property_set_uint(OBJECT(&s->eth[i]), "tx-ring-num",
475                                  FSL_IMX6UL_ETH_NUM_TX_RINGS, &error_abort);
476         qdev_set_nic_properties(DEVICE(&s->eth[i]), &nd_table[i]);
477         sysbus_realize(SYS_BUS_DEVICE(&s->eth[i]), &error_abort);
478 
479         sysbus_mmio_map(SYS_BUS_DEVICE(&s->eth[i]), 0,
480                         FSL_IMX6UL_ENETn_ADDR[i]);
481 
482         sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 0,
483                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
484                                             FSL_IMX6UL_ENETn_IRQ[i]));
485 
486         sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 1,
487                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
488                                             FSL_IMX6UL_ENETn_TIMER_IRQ[i]));
489     }
490 
491     /*
492      * USB PHYs
493      */
494     for (i = 0; i < FSL_IMX6UL_NUM_USB_PHYS; i++) {
495         static const hwaddr
496                      FSL_IMX6UL_USB_PHYn_ADDR[FSL_IMX6UL_NUM_USB_PHYS] = {
497             FSL_IMX6UL_USBPHY1_ADDR,
498             FSL_IMX6UL_USBPHY2_ADDR,
499         };
500 
501         sysbus_realize(SYS_BUS_DEVICE(&s->usbphy[i]), &error_abort);
502         sysbus_mmio_map(SYS_BUS_DEVICE(&s->usbphy[i]), 0,
503                         FSL_IMX6UL_USB_PHYn_ADDR[i]);
504     }
505 
506     /*
507      * USBs
508      */
509     for (i = 0; i < FSL_IMX6UL_NUM_USBS; i++) {
510         static const hwaddr FSL_IMX6UL_USB02_USBn_ADDR[FSL_IMX6UL_NUM_USBS] = {
511             FSL_IMX6UL_USBO2_USB1_ADDR,
512             FSL_IMX6UL_USBO2_USB2_ADDR,
513         };
514 
515         static const int FSL_IMX6UL_USBn_IRQ[] = {
516             FSL_IMX6UL_USB1_IRQ,
517             FSL_IMX6UL_USB2_IRQ,
518         };
519 
520         sysbus_realize(SYS_BUS_DEVICE(&s->usb[i]), &error_abort);
521         sysbus_mmio_map(SYS_BUS_DEVICE(&s->usb[i]), 0,
522                         FSL_IMX6UL_USB02_USBn_ADDR[i]);
523         sysbus_connect_irq(SYS_BUS_DEVICE(&s->usb[i]), 0,
524                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
525                                             FSL_IMX6UL_USBn_IRQ[i]));
526     }
527 
528     /*
529      * USDHCs
530      */
531     for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
532         static const hwaddr FSL_IMX6UL_USDHCn_ADDR[FSL_IMX6UL_NUM_USDHCS] = {
533             FSL_IMX6UL_USDHC1_ADDR,
534             FSL_IMX6UL_USDHC2_ADDR,
535         };
536 
537         static const int FSL_IMX6UL_USDHCn_IRQ[FSL_IMX6UL_NUM_USDHCS] = {
538             FSL_IMX6UL_USDHC1_IRQ,
539             FSL_IMX6UL_USDHC2_IRQ,
540         };
541 
542         object_property_set_uint(OBJECT(&s->usdhc[i]), "vendor",
543                                  SDHCI_VENDOR_IMX, &error_abort);
544         sysbus_realize(SYS_BUS_DEVICE(&s->usdhc[i]), &error_abort);
545 
546         sysbus_mmio_map(SYS_BUS_DEVICE(&s->usdhc[i]), 0,
547                         FSL_IMX6UL_USDHCn_ADDR[i]);
548 
549         sysbus_connect_irq(SYS_BUS_DEVICE(&s->usdhc[i]), 0,
550                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
551                                             FSL_IMX6UL_USDHCn_IRQ[i]));
552     }
553 
554     /*
555      * SNVS
556      */
557     sysbus_realize(SYS_BUS_DEVICE(&s->snvs), &error_abort);
558     sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0, FSL_IMX6UL_SNVS_HP_ADDR);
559 
560     /*
561      * Watchdogs
562      */
563     for (i = 0; i < FSL_IMX6UL_NUM_WDTS; i++) {
564         static const hwaddr FSL_IMX6UL_WDOGn_ADDR[FSL_IMX6UL_NUM_WDTS] = {
565             FSL_IMX6UL_WDOG1_ADDR,
566             FSL_IMX6UL_WDOG2_ADDR,
567             FSL_IMX6UL_WDOG3_ADDR,
568         };
569 
570         static const int FSL_IMX6UL_WDOGn_IRQ[FSL_IMX6UL_NUM_WDTS] = {
571             FSL_IMX6UL_WDOG1_IRQ,
572             FSL_IMX6UL_WDOG2_IRQ,
573             FSL_IMX6UL_WDOG3_IRQ,
574         };
575 
576         object_property_set_bool(OBJECT(&s->wdt[i]), "pretimeout-support",
577                                  true, &error_abort);
578         sysbus_realize(SYS_BUS_DEVICE(&s->wdt[i]), &error_abort);
579 
580         sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0,
581                         FSL_IMX6UL_WDOGn_ADDR[i]);
582         sysbus_connect_irq(SYS_BUS_DEVICE(&s->wdt[i]), 0,
583                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
584                                             FSL_IMX6UL_WDOGn_IRQ[i]));
585     }
586 
587     /*
588      * SDMA
589      */
590     create_unimplemented_device("sdma", FSL_IMX6UL_SDMA_ADDR,
591                                 FSL_IMX6UL_SDMA_SIZE);
592 
593     /*
594      * SAIs (Audio SSI (Synchronous Serial Interface))
595      */
596     for (i = 0; i < FSL_IMX6UL_NUM_SAIS; i++) {
597         static const hwaddr FSL_IMX6UL_SAIn_ADDR[FSL_IMX6UL_NUM_SAIS] = {
598             FSL_IMX6UL_SAI1_ADDR,
599             FSL_IMX6UL_SAI2_ADDR,
600             FSL_IMX6UL_SAI3_ADDR,
601         };
602 
603         snprintf(name, NAME_SIZE, "sai%d", i);
604         create_unimplemented_device(name, FSL_IMX6UL_SAIn_ADDR[i],
605                                     FSL_IMX6UL_SAIn_SIZE);
606     }
607 
608     /*
609      * PWMs
610      */
611     for (i = 0; i < FSL_IMX6UL_NUM_PWMS; i++) {
612         static const hwaddr FSL_IMX6UL_PWMn_ADDR[FSL_IMX6UL_NUM_PWMS] = {
613             FSL_IMX6UL_PWM1_ADDR,
614             FSL_IMX6UL_PWM2_ADDR,
615             FSL_IMX6UL_PWM3_ADDR,
616             FSL_IMX6UL_PWM4_ADDR,
617             FSL_IMX6UL_PWM5_ADDR,
618             FSL_IMX6UL_PWM6_ADDR,
619             FSL_IMX6UL_PWM7_ADDR,
620             FSL_IMX6UL_PWM8_ADDR,
621         };
622 
623         snprintf(name, NAME_SIZE, "pwm%d", i);
624         create_unimplemented_device(name, FSL_IMX6UL_PWMn_ADDR[i],
625                                     FSL_IMX6UL_PWMn_SIZE);
626     }
627 
628     /*
629      * Audio ASRC (asynchronous sample rate converter)
630      */
631     create_unimplemented_device("asrc", FSL_IMX6UL_ASRC_ADDR,
632                                 FSL_IMX6UL_ASRC_SIZE);
633 
634     /*
635      * CANs
636      */
637     for (i = 0; i < FSL_IMX6UL_NUM_CANS; i++) {
638         static const hwaddr FSL_IMX6UL_CANn_ADDR[FSL_IMX6UL_NUM_CANS] = {
639             FSL_IMX6UL_CAN1_ADDR,
640             FSL_IMX6UL_CAN2_ADDR,
641         };
642 
643         snprintf(name, NAME_SIZE, "can%d", i);
644         create_unimplemented_device(name, FSL_IMX6UL_CANn_ADDR[i],
645                                     FSL_IMX6UL_CANn_SIZE);
646     }
647 
648     /*
649      * APHB_DMA
650      */
651     create_unimplemented_device("aphb_dma", FSL_IMX6UL_APBH_DMA_ADDR,
652                                 FSL_IMX6UL_APBH_DMA_SIZE);
653 
654     /*
655      * ADCs
656      */
657     for (i = 0; i < FSL_IMX6UL_NUM_ADCS; i++) {
658         static const hwaddr FSL_IMX6UL_ADCn_ADDR[FSL_IMX6UL_NUM_ADCS] = {
659             FSL_IMX6UL_ADC1_ADDR,
660             FSL_IMX6UL_ADC2_ADDR,
661         };
662 
663         snprintf(name, NAME_SIZE, "adc%d", i);
664         create_unimplemented_device(name, FSL_IMX6UL_ADCn_ADDR[i],
665                                     FSL_IMX6UL_ADCn_SIZE);
666     }
667 
668     /*
669      * LCD
670      */
671     create_unimplemented_device("lcdif", FSL_IMX6UL_LCDIF_ADDR,
672                                 FSL_IMX6UL_LCDIF_SIZE);
673 
674     /*
675      * CSU
676      */
677     create_unimplemented_device("csu", FSL_IMX6UL_CSU_ADDR,
678                                 FSL_IMX6UL_CSU_SIZE);
679 
680     /*
681      * TZASC
682      */
683     create_unimplemented_device("tzasc", FSL_IMX6UL_TZASC_ADDR,
684                                 FSL_IMX6UL_TZASC_SIZE);
685 
686     /*
687      * ROM memory
688      */
689     memory_region_init_rom(&s->rom, OBJECT(dev), "imx6ul.rom",
690                            FSL_IMX6UL_ROM_SIZE, &error_abort);
691     memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_ROM_ADDR,
692                                 &s->rom);
693 
694     /*
695      * CAAM memory
696      */
697     memory_region_init_rom(&s->caam, OBJECT(dev), "imx6ul.caam",
698                            FSL_IMX6UL_CAAM_MEM_SIZE, &error_abort);
699     memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_CAAM_MEM_ADDR,
700                                 &s->caam);
701 
702     /*
703      * OCRAM memory
704      */
705     memory_region_init_ram(&s->ocram, NULL, "imx6ul.ocram",
706                            FSL_IMX6UL_OCRAM_MEM_SIZE,
707                            &error_abort);
708     memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_OCRAM_MEM_ADDR,
709                                 &s->ocram);
710 
711     /*
712      * internal OCRAM (128 KB) is aliased over 512 KB
713      */
714     memory_region_init_alias(&s->ocram_alias, OBJECT(dev),
715                              "imx6ul.ocram_alias", &s->ocram, 0,
716                              FSL_IMX6UL_OCRAM_ALIAS_SIZE);
717     memory_region_add_subregion(get_system_memory(),
718                                 FSL_IMX6UL_OCRAM_ALIAS_ADDR, &s->ocram_alias);
719 }
720 
721 static Property fsl_imx6ul_properties[] = {
722     DEFINE_PROP_UINT32("fec1-phy-num", FslIMX6ULState, phy_num[0], 0),
723     DEFINE_PROP_UINT32("fec2-phy-num", FslIMX6ULState, phy_num[1], 1),
724     DEFINE_PROP_BOOL("fec1-phy-connected", FslIMX6ULState, phy_connected[0],
725                      true),
726     DEFINE_PROP_BOOL("fec2-phy-connected", FslIMX6ULState, phy_connected[1],
727                      true),
728     DEFINE_PROP_END_OF_LIST(),
729 };
730 
731 static void fsl_imx6ul_class_init(ObjectClass *oc, void *data)
732 {
733     DeviceClass *dc = DEVICE_CLASS(oc);
734 
735     device_class_set_props(dc, fsl_imx6ul_properties);
736     dc->realize = fsl_imx6ul_realize;
737     dc->desc = "i.MX6UL SOC";
738     /* Reason: Uses serial_hds and nd_table in realize() directly */
739     dc->user_creatable = false;
740 }
741 
742 static const TypeInfo fsl_imx6ul_type_info = {
743     .name = TYPE_FSL_IMX6UL,
744     .parent = TYPE_DEVICE,
745     .instance_size = sizeof(FslIMX6ULState),
746     .instance_init = fsl_imx6ul_init,
747     .class_init = fsl_imx6ul_class_init,
748 };
749 
750 static void fsl_imx6ul_register_types(void)
751 {
752     type_register_static(&fsl_imx6ul_type_info);
753 }
754 type_init(fsl_imx6ul_register_types)
755