xref: /openbmc/qemu/hw/arm/fsl-imx7.c (revision 784155cd)
1 /*
2  * Copyright (c) 2018, Impinj, Inc.
3  *
4  * i.MX7 SoC definitions
5  *
6  * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
7  *
8  * Based on hw/arm/fsl-imx6.c
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  */
20 
21 #include "qemu/osdep.h"
22 #include "qapi/error.h"
23 #include "hw/arm/fsl-imx7.h"
24 #include "hw/misc/unimp.h"
25 #include "hw/boards.h"
26 #include "sysemu/sysemu.h"
27 #include "qemu/error-report.h"
28 #include "qemu/module.h"
29 
30 #define NAME_SIZE 20
31 
32 static void fsl_imx7_init(Object *obj)
33 {
34     MachineState *ms = MACHINE(qdev_get_machine());
35     FslIMX7State *s = FSL_IMX7(obj);
36     char name[NAME_SIZE];
37     int i;
38 
39     /*
40      * CPUs
41      */
42     for (i = 0; i < MIN(ms->smp.cpus, FSL_IMX7_NUM_CPUS); i++) {
43         snprintf(name, NAME_SIZE, "cpu%d", i);
44         object_initialize_child(obj, name, &s->cpu[i],
45                                 ARM_CPU_TYPE_NAME("cortex-a7"));
46     }
47 
48     /*
49      * A7MPCORE
50      */
51     object_initialize_child(obj, "a7mpcore", &s->a7mpcore,
52                             TYPE_A15MPCORE_PRIV);
53 
54     /*
55      * GPIOs
56      */
57     for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
58         snprintf(name, NAME_SIZE, "gpio%d", i);
59         object_initialize_child(obj, name, &s->gpio[i], TYPE_IMX_GPIO);
60     }
61 
62     /*
63      * GPTs
64      */
65     for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
66         snprintf(name, NAME_SIZE, "gpt%d", i);
67         object_initialize_child(obj, name, &s->gpt[i], TYPE_IMX7_GPT);
68     }
69 
70     /*
71      * CCM
72      */
73     object_initialize_child(obj, "ccm", &s->ccm, TYPE_IMX7_CCM);
74 
75     /*
76      * Analog
77      */
78     object_initialize_child(obj, "analog", &s->analog, TYPE_IMX7_ANALOG);
79 
80     /*
81      * GPCv2
82      */
83     object_initialize_child(obj, "gpcv2", &s->gpcv2, TYPE_IMX_GPCV2);
84 
85     /*
86      * SRC
87      */
88     object_initialize_child(obj, "src", &s->src, TYPE_IMX7_SRC);
89 
90     /*
91      * ECSPIs
92      */
93     for (i = 0; i < FSL_IMX7_NUM_ECSPIS; i++) {
94         snprintf(name, NAME_SIZE, "spi%d", i + 1);
95         object_initialize_child(obj, name, &s->spi[i], TYPE_IMX_SPI);
96     }
97 
98     /*
99      * I2Cs
100      */
101     for (i = 0; i < FSL_IMX7_NUM_I2CS; i++) {
102         snprintf(name, NAME_SIZE, "i2c%d", i + 1);
103         object_initialize_child(obj, name, &s->i2c[i], TYPE_IMX_I2C);
104     }
105 
106     /*
107      * UARTs
108      */
109     for (i = 0; i < FSL_IMX7_NUM_UARTS; i++) {
110             snprintf(name, NAME_SIZE, "uart%d", i);
111             object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL);
112     }
113 
114     /*
115      * Ethernets
116      */
117     for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
118             snprintf(name, NAME_SIZE, "eth%d", i);
119             object_initialize_child(obj, name, &s->eth[i], TYPE_IMX_ENET);
120     }
121 
122     /*
123      * SDHCIs
124      */
125     for (i = 0; i < FSL_IMX7_NUM_USDHCS; i++) {
126             snprintf(name, NAME_SIZE, "usdhc%d", i);
127             object_initialize_child(obj, name, &s->usdhc[i], TYPE_IMX_USDHC);
128     }
129 
130     /*
131      * SNVS
132      */
133     object_initialize_child(obj, "snvs", &s->snvs, TYPE_IMX7_SNVS);
134 
135     /*
136      * Watchdogs
137      */
138     for (i = 0; i < FSL_IMX7_NUM_WDTS; i++) {
139             snprintf(name, NAME_SIZE, "wdt%d", i);
140             object_initialize_child(obj, name, &s->wdt[i], TYPE_IMX2_WDT);
141     }
142 
143     /*
144      * GPR
145      */
146     object_initialize_child(obj, "gpr", &s->gpr, TYPE_IMX7_GPR);
147 
148     /*
149      * PCIE
150      */
151     object_initialize_child(obj, "pcie", &s->pcie, TYPE_DESIGNWARE_PCIE_HOST);
152 
153     /*
154      * USBs
155      */
156     for (i = 0; i < FSL_IMX7_NUM_USBS; i++) {
157         snprintf(name, NAME_SIZE, "usb%d", i);
158         object_initialize_child(obj, name, &s->usb[i], TYPE_CHIPIDEA);
159     }
160 }
161 
162 static void fsl_imx7_realize(DeviceState *dev, Error **errp)
163 {
164     MachineState *ms = MACHINE(qdev_get_machine());
165     FslIMX7State *s = FSL_IMX7(dev);
166     Object *o;
167     int i;
168     qemu_irq irq;
169     char name[NAME_SIZE];
170     unsigned int smp_cpus = ms->smp.cpus;
171 
172     if (smp_cpus > FSL_IMX7_NUM_CPUS) {
173         error_setg(errp, "%s: Only %d CPUs are supported (%d requested)",
174                    TYPE_FSL_IMX7, FSL_IMX7_NUM_CPUS, smp_cpus);
175         return;
176     }
177 
178     /*
179      * CPUs
180      */
181     for (i = 0; i < smp_cpus; i++) {
182         o = OBJECT(&s->cpu[i]);
183 
184         /* On uniprocessor, the CBAR is set to 0 */
185         if (smp_cpus > 1) {
186             object_property_set_int(o, "reset-cbar", FSL_IMX7_A7MPCORE_ADDR,
187                                     &error_abort);
188         }
189 
190         if (i) {
191             /*
192              * Secondary CPUs start in powered-down state (and can be
193              * powered up via the SRC system reset controller)
194              */
195             object_property_set_bool(o, "start-powered-off", true,
196                                      &error_abort);
197         }
198 
199         qdev_realize(DEVICE(o), NULL, &error_abort);
200     }
201 
202     /*
203      * A7MPCORE
204      */
205     object_property_set_int(OBJECT(&s->a7mpcore), "num-cpu", smp_cpus,
206                             &error_abort);
207     object_property_set_int(OBJECT(&s->a7mpcore), "num-irq",
208                             FSL_IMX7_MAX_IRQ + GIC_INTERNAL, &error_abort);
209 
210     sysbus_realize(SYS_BUS_DEVICE(&s->a7mpcore), &error_abort);
211     sysbus_mmio_map(SYS_BUS_DEVICE(&s->a7mpcore), 0, FSL_IMX7_A7MPCORE_ADDR);
212 
213     for (i = 0; i < smp_cpus; i++) {
214         SysBusDevice *sbd = SYS_BUS_DEVICE(&s->a7mpcore);
215         DeviceState  *d   = DEVICE(qemu_get_cpu(i));
216 
217         irq = qdev_get_gpio_in(d, ARM_CPU_IRQ);
218         sysbus_connect_irq(sbd, i, irq);
219         irq = qdev_get_gpio_in(d, ARM_CPU_FIQ);
220         sysbus_connect_irq(sbd, i + smp_cpus, irq);
221         irq = qdev_get_gpio_in(d, ARM_CPU_VIRQ);
222         sysbus_connect_irq(sbd, i + 2 * smp_cpus, irq);
223         irq = qdev_get_gpio_in(d, ARM_CPU_VFIQ);
224         sysbus_connect_irq(sbd, i + 3 * smp_cpus, irq);
225     }
226 
227     /*
228      * A7MPCORE DAP
229      */
230     create_unimplemented_device("a7mpcore-dap", FSL_IMX7_A7MPCORE_DAP_ADDR,
231                                 FSL_IMX7_A7MPCORE_DAP_SIZE);
232 
233     /*
234      * GPTs
235      */
236     for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
237         static const hwaddr FSL_IMX7_GPTn_ADDR[FSL_IMX7_NUM_GPTS] = {
238             FSL_IMX7_GPT1_ADDR,
239             FSL_IMX7_GPT2_ADDR,
240             FSL_IMX7_GPT3_ADDR,
241             FSL_IMX7_GPT4_ADDR,
242         };
243 
244         static const int FSL_IMX7_GPTn_IRQ[FSL_IMX7_NUM_GPTS] = {
245             FSL_IMX7_GPT1_IRQ,
246             FSL_IMX7_GPT2_IRQ,
247             FSL_IMX7_GPT3_IRQ,
248             FSL_IMX7_GPT4_IRQ,
249         };
250 
251         s->gpt[i].ccm = IMX_CCM(&s->ccm);
252         sysbus_realize(SYS_BUS_DEVICE(&s->gpt[i]), &error_abort);
253         sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0, FSL_IMX7_GPTn_ADDR[i]);
254         sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0,
255                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
256                                             FSL_IMX7_GPTn_IRQ[i]));
257     }
258 
259     /*
260      * GPIOs
261      */
262     for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
263         static const hwaddr FSL_IMX7_GPIOn_ADDR[FSL_IMX7_NUM_GPIOS] = {
264             FSL_IMX7_GPIO1_ADDR,
265             FSL_IMX7_GPIO2_ADDR,
266             FSL_IMX7_GPIO3_ADDR,
267             FSL_IMX7_GPIO4_ADDR,
268             FSL_IMX7_GPIO5_ADDR,
269             FSL_IMX7_GPIO6_ADDR,
270             FSL_IMX7_GPIO7_ADDR,
271         };
272 
273         static const int FSL_IMX7_GPIOn_LOW_IRQ[FSL_IMX7_NUM_GPIOS] = {
274             FSL_IMX7_GPIO1_LOW_IRQ,
275             FSL_IMX7_GPIO2_LOW_IRQ,
276             FSL_IMX7_GPIO3_LOW_IRQ,
277             FSL_IMX7_GPIO4_LOW_IRQ,
278             FSL_IMX7_GPIO5_LOW_IRQ,
279             FSL_IMX7_GPIO6_LOW_IRQ,
280             FSL_IMX7_GPIO7_LOW_IRQ,
281         };
282 
283         static const int FSL_IMX7_GPIOn_HIGH_IRQ[FSL_IMX7_NUM_GPIOS] = {
284             FSL_IMX7_GPIO1_HIGH_IRQ,
285             FSL_IMX7_GPIO2_HIGH_IRQ,
286             FSL_IMX7_GPIO3_HIGH_IRQ,
287             FSL_IMX7_GPIO4_HIGH_IRQ,
288             FSL_IMX7_GPIO5_HIGH_IRQ,
289             FSL_IMX7_GPIO6_HIGH_IRQ,
290             FSL_IMX7_GPIO7_HIGH_IRQ,
291         };
292 
293         sysbus_realize(SYS_BUS_DEVICE(&s->gpio[i]), &error_abort);
294         sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0,
295                         FSL_IMX7_GPIOn_ADDR[i]);
296 
297         sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0,
298                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
299                                             FSL_IMX7_GPIOn_LOW_IRQ[i]));
300 
301         sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 1,
302                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
303                                             FSL_IMX7_GPIOn_HIGH_IRQ[i]));
304     }
305 
306     /*
307      * IOMUXC and IOMUXC_LPSR
308      */
309     create_unimplemented_device("iomuxc", FSL_IMX7_IOMUXC_ADDR,
310                                 FSL_IMX7_IOMUXC_SIZE);
311     create_unimplemented_device("iomuxc_lspr", FSL_IMX7_IOMUXC_LPSR_ADDR,
312                                 FSL_IMX7_IOMUXC_LPSR_SIZE);
313 
314     /*
315      * CCM
316      */
317     sysbus_realize(SYS_BUS_DEVICE(&s->ccm), &error_abort);
318     sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX7_CCM_ADDR);
319 
320     /*
321      * Analog
322      */
323     sysbus_realize(SYS_BUS_DEVICE(&s->analog), &error_abort);
324     sysbus_mmio_map(SYS_BUS_DEVICE(&s->analog), 0, FSL_IMX7_ANALOG_ADDR);
325 
326     /*
327      * GPCv2
328      */
329     sysbus_realize(SYS_BUS_DEVICE(&s->gpcv2), &error_abort);
330     sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpcv2), 0, FSL_IMX7_GPC_ADDR);
331 
332     /*
333      * ECSPIs
334      */
335     for (i = 0; i < FSL_IMX7_NUM_ECSPIS; i++) {
336         static const hwaddr FSL_IMX7_SPIn_ADDR[FSL_IMX7_NUM_ECSPIS] = {
337             FSL_IMX7_ECSPI1_ADDR,
338             FSL_IMX7_ECSPI2_ADDR,
339             FSL_IMX7_ECSPI3_ADDR,
340             FSL_IMX7_ECSPI4_ADDR,
341         };
342 
343         static const int FSL_IMX7_SPIn_IRQ[FSL_IMX7_NUM_ECSPIS] = {
344             FSL_IMX7_ECSPI1_IRQ,
345             FSL_IMX7_ECSPI2_IRQ,
346             FSL_IMX7_ECSPI3_IRQ,
347             FSL_IMX7_ECSPI4_IRQ,
348         };
349 
350         /* Initialize the SPI */
351         sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), &error_abort);
352         sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0,
353                         FSL_IMX7_SPIn_ADDR[i]);
354         sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0,
355                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
356                                             FSL_IMX7_SPIn_IRQ[i]));
357     }
358 
359     /*
360      * I2Cs
361      */
362     for (i = 0; i < FSL_IMX7_NUM_I2CS; i++) {
363         static const hwaddr FSL_IMX7_I2Cn_ADDR[FSL_IMX7_NUM_I2CS] = {
364             FSL_IMX7_I2C1_ADDR,
365             FSL_IMX7_I2C2_ADDR,
366             FSL_IMX7_I2C3_ADDR,
367             FSL_IMX7_I2C4_ADDR,
368         };
369 
370         static const int FSL_IMX7_I2Cn_IRQ[FSL_IMX7_NUM_I2CS] = {
371             FSL_IMX7_I2C1_IRQ,
372             FSL_IMX7_I2C2_IRQ,
373             FSL_IMX7_I2C3_IRQ,
374             FSL_IMX7_I2C4_IRQ,
375         };
376 
377         sysbus_realize(SYS_BUS_DEVICE(&s->i2c[i]), &error_abort);
378         sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, FSL_IMX7_I2Cn_ADDR[i]);
379 
380         sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
381                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
382                                             FSL_IMX7_I2Cn_IRQ[i]));
383     }
384 
385     /*
386      * UARTs
387      */
388     for (i = 0; i < FSL_IMX7_NUM_UARTS; i++) {
389         static const hwaddr FSL_IMX7_UARTn_ADDR[FSL_IMX7_NUM_UARTS] = {
390             FSL_IMX7_UART1_ADDR,
391             FSL_IMX7_UART2_ADDR,
392             FSL_IMX7_UART3_ADDR,
393             FSL_IMX7_UART4_ADDR,
394             FSL_IMX7_UART5_ADDR,
395             FSL_IMX7_UART6_ADDR,
396             FSL_IMX7_UART7_ADDR,
397         };
398 
399         static const int FSL_IMX7_UARTn_IRQ[FSL_IMX7_NUM_UARTS] = {
400             FSL_IMX7_UART1_IRQ,
401             FSL_IMX7_UART2_IRQ,
402             FSL_IMX7_UART3_IRQ,
403             FSL_IMX7_UART4_IRQ,
404             FSL_IMX7_UART5_IRQ,
405             FSL_IMX7_UART6_IRQ,
406             FSL_IMX7_UART7_IRQ,
407         };
408 
409 
410         qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", serial_hd(i));
411 
412         sysbus_realize(SYS_BUS_DEVICE(&s->uart[i]), &error_abort);
413 
414         sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, FSL_IMX7_UARTn_ADDR[i]);
415 
416         irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_UARTn_IRQ[i]);
417         sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0, irq);
418     }
419 
420     /*
421      * Ethernets
422      *
423      * We must use two loops since phy_connected affects the other interface
424      * and we have to set all properties before calling sysbus_realize().
425      */
426     for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
427         object_property_set_bool(OBJECT(&s->eth[i]), "phy-connected",
428                                  s->phy_connected[i], &error_abort);
429         /*
430          * If the MDIO bus on this controller is not connected, assume the
431          * other controller provides support for it.
432          */
433         if (!s->phy_connected[i]) {
434             object_property_set_link(OBJECT(&s->eth[1 - i]), "phy-consumer",
435                                      OBJECT(&s->eth[i]), &error_abort);
436         }
437     }
438 
439     for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
440         static const hwaddr FSL_IMX7_ENETn_ADDR[FSL_IMX7_NUM_ETHS] = {
441             FSL_IMX7_ENET1_ADDR,
442             FSL_IMX7_ENET2_ADDR,
443         };
444 
445         object_property_set_uint(OBJECT(&s->eth[i]), "phy-num",
446                                  s->phy_num[i], &error_abort);
447         object_property_set_uint(OBJECT(&s->eth[i]), "tx-ring-num",
448                                  FSL_IMX7_ETH_NUM_TX_RINGS, &error_abort);
449         qdev_set_nic_properties(DEVICE(&s->eth[i]), &nd_table[i]);
450         sysbus_realize(SYS_BUS_DEVICE(&s->eth[i]), &error_abort);
451 
452         sysbus_mmio_map(SYS_BUS_DEVICE(&s->eth[i]), 0, FSL_IMX7_ENETn_ADDR[i]);
453 
454         irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_ENET_IRQ(i, 0));
455         sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 0, irq);
456         irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_ENET_IRQ(i, 3));
457         sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 1, irq);
458     }
459 
460     /*
461      * USDHCs
462      */
463     for (i = 0; i < FSL_IMX7_NUM_USDHCS; i++) {
464         static const hwaddr FSL_IMX7_USDHCn_ADDR[FSL_IMX7_NUM_USDHCS] = {
465             FSL_IMX7_USDHC1_ADDR,
466             FSL_IMX7_USDHC2_ADDR,
467             FSL_IMX7_USDHC3_ADDR,
468         };
469 
470         static const int FSL_IMX7_USDHCn_IRQ[FSL_IMX7_NUM_USDHCS] = {
471             FSL_IMX7_USDHC1_IRQ,
472             FSL_IMX7_USDHC2_IRQ,
473             FSL_IMX7_USDHC3_IRQ,
474         };
475 
476         object_property_set_uint(OBJECT(&s->usdhc[i]), "vendor",
477                                  SDHCI_VENDOR_IMX, &error_abort);
478         sysbus_realize(SYS_BUS_DEVICE(&s->usdhc[i]), &error_abort);
479 
480         sysbus_mmio_map(SYS_BUS_DEVICE(&s->usdhc[i]), 0,
481                         FSL_IMX7_USDHCn_ADDR[i]);
482 
483         irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_USDHCn_IRQ[i]);
484         sysbus_connect_irq(SYS_BUS_DEVICE(&s->usdhc[i]), 0, irq);
485     }
486 
487     /*
488      * SNVS
489      */
490     sysbus_realize(SYS_BUS_DEVICE(&s->snvs), &error_abort);
491     sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0, FSL_IMX7_SNVS_HP_ADDR);
492 
493     /*
494      * SRC
495      */
496     sysbus_realize(SYS_BUS_DEVICE(&s->src), &error_abort);
497     sysbus_mmio_map(SYS_BUS_DEVICE(&s->src), 0, FSL_IMX7_SRC_ADDR);
498 
499     /*
500      * Watchdogs
501      */
502     for (i = 0; i < FSL_IMX7_NUM_WDTS; i++) {
503         static const hwaddr FSL_IMX7_WDOGn_ADDR[FSL_IMX7_NUM_WDTS] = {
504             FSL_IMX7_WDOG1_ADDR,
505             FSL_IMX7_WDOG2_ADDR,
506             FSL_IMX7_WDOG3_ADDR,
507             FSL_IMX7_WDOG4_ADDR,
508         };
509         static const int FSL_IMX7_WDOGn_IRQ[FSL_IMX7_NUM_WDTS] = {
510             FSL_IMX7_WDOG1_IRQ,
511             FSL_IMX7_WDOG2_IRQ,
512             FSL_IMX7_WDOG3_IRQ,
513             FSL_IMX7_WDOG4_IRQ,
514         };
515 
516         object_property_set_bool(OBJECT(&s->wdt[i]), "pretimeout-support",
517                                  true, &error_abort);
518         sysbus_realize(SYS_BUS_DEVICE(&s->wdt[i]), &error_abort);
519 
520         sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, FSL_IMX7_WDOGn_ADDR[i]);
521         sysbus_connect_irq(SYS_BUS_DEVICE(&s->wdt[i]), 0,
522                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
523                                             FSL_IMX7_WDOGn_IRQ[i]));
524     }
525 
526     /*
527      * SDMA
528      */
529     create_unimplemented_device("sdma", FSL_IMX7_SDMA_ADDR, FSL_IMX7_SDMA_SIZE);
530 
531     /*
532      * CAAM
533      */
534     create_unimplemented_device("caam", FSL_IMX7_CAAM_ADDR, FSL_IMX7_CAAM_SIZE);
535 
536     /*
537      * PWMs
538      */
539     for (i = 0; i < FSL_IMX7_NUM_PWMS; i++) {
540         static const hwaddr FSL_IMX7_PWMn_ADDR[FSL_IMX7_NUM_PWMS] = {
541             FSL_IMX7_PWM1_ADDR,
542             FSL_IMX7_PWM2_ADDR,
543             FSL_IMX7_PWM3_ADDR,
544             FSL_IMX7_PWM4_ADDR,
545         };
546 
547         snprintf(name, NAME_SIZE, "pwm%d", i);
548         create_unimplemented_device(name, FSL_IMX7_PWMn_ADDR[i],
549                                     FSL_IMX7_PWMn_SIZE);
550     }
551 
552     /*
553      * CANs
554      */
555     for (i = 0; i < FSL_IMX7_NUM_CANS; i++) {
556         static const hwaddr FSL_IMX7_CANn_ADDR[FSL_IMX7_NUM_CANS] = {
557             FSL_IMX7_CAN1_ADDR,
558             FSL_IMX7_CAN2_ADDR,
559         };
560 
561         snprintf(name, NAME_SIZE, "can%d", i);
562         create_unimplemented_device(name, FSL_IMX7_CANn_ADDR[i],
563                                     FSL_IMX7_CANn_SIZE);
564     }
565 
566     /*
567      * SAIs (Audio SSI (Synchronous Serial Interface))
568      */
569     for (i = 0; i < FSL_IMX7_NUM_SAIS; i++) {
570         static const hwaddr FSL_IMX7_SAIn_ADDR[FSL_IMX7_NUM_SAIS] = {
571             FSL_IMX7_SAI1_ADDR,
572             FSL_IMX7_SAI2_ADDR,
573             FSL_IMX7_SAI3_ADDR,
574         };
575 
576         snprintf(name, NAME_SIZE, "sai%d", i);
577         create_unimplemented_device(name, FSL_IMX7_SAIn_ADDR[i],
578                                     FSL_IMX7_SAIn_SIZE);
579     }
580 
581     /*
582      * OCOTP
583      */
584     create_unimplemented_device("ocotp", FSL_IMX7_OCOTP_ADDR,
585                                 FSL_IMX7_OCOTP_SIZE);
586 
587     /*
588      * GPR
589      */
590     sysbus_realize(SYS_BUS_DEVICE(&s->gpr), &error_abort);
591     sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpr), 0, FSL_IMX7_IOMUXC_GPR_ADDR);
592 
593     /*
594      * PCIE
595      */
596     sysbus_realize(SYS_BUS_DEVICE(&s->pcie), &error_abort);
597     sysbus_mmio_map(SYS_BUS_DEVICE(&s->pcie), 0, FSL_IMX7_PCIE_REG_ADDR);
598 
599     irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTA_IRQ);
600     sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 0, irq);
601     irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTB_IRQ);
602     sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 1, irq);
603     irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTC_IRQ);
604     sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 2, irq);
605     irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTD_IRQ);
606     sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 3, irq);
607 
608     /*
609      * USBs
610      */
611     for (i = 0; i < FSL_IMX7_NUM_USBS; i++) {
612         static const hwaddr FSL_IMX7_USBMISCn_ADDR[FSL_IMX7_NUM_USBS] = {
613             FSL_IMX7_USBMISC1_ADDR,
614             FSL_IMX7_USBMISC2_ADDR,
615             FSL_IMX7_USBMISC3_ADDR,
616         };
617 
618         static const hwaddr FSL_IMX7_USBn_ADDR[FSL_IMX7_NUM_USBS] = {
619             FSL_IMX7_USB1_ADDR,
620             FSL_IMX7_USB2_ADDR,
621             FSL_IMX7_USB3_ADDR,
622         };
623 
624         static const int FSL_IMX7_USBn_IRQ[FSL_IMX7_NUM_USBS] = {
625             FSL_IMX7_USB1_IRQ,
626             FSL_IMX7_USB2_IRQ,
627             FSL_IMX7_USB3_IRQ,
628         };
629 
630         sysbus_realize(SYS_BUS_DEVICE(&s->usb[i]), &error_abort);
631         sysbus_mmio_map(SYS_BUS_DEVICE(&s->usb[i]), 0,
632                         FSL_IMX7_USBn_ADDR[i]);
633 
634         irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_USBn_IRQ[i]);
635         sysbus_connect_irq(SYS_BUS_DEVICE(&s->usb[i]), 0, irq);
636 
637         snprintf(name, NAME_SIZE, "usbmisc%d", i);
638         create_unimplemented_device(name, FSL_IMX7_USBMISCn_ADDR[i],
639                                     FSL_IMX7_USBMISCn_SIZE);
640     }
641 
642     /*
643      * ADCs
644      */
645     for (i = 0; i < FSL_IMX7_NUM_ADCS; i++) {
646         static const hwaddr FSL_IMX7_ADCn_ADDR[FSL_IMX7_NUM_ADCS] = {
647             FSL_IMX7_ADC1_ADDR,
648             FSL_IMX7_ADC2_ADDR,
649         };
650 
651         snprintf(name, NAME_SIZE, "adc%d", i);
652         create_unimplemented_device(name, FSL_IMX7_ADCn_ADDR[i],
653                                     FSL_IMX7_ADCn_SIZE);
654     }
655 
656     /*
657      * LCD
658      */
659     create_unimplemented_device("lcdif", FSL_IMX7_LCDIF_ADDR,
660                                 FSL_IMX7_LCDIF_SIZE);
661 
662     /*
663      * DMA APBH
664      */
665     create_unimplemented_device("dma-apbh", FSL_IMX7_DMA_APBH_ADDR,
666                                 FSL_IMX7_DMA_APBH_SIZE);
667     /*
668      * PCIe PHY
669      */
670     create_unimplemented_device("pcie-phy", FSL_IMX7_PCIE_PHY_ADDR,
671                                 FSL_IMX7_PCIE_PHY_SIZE);
672 
673     /*
674      * CSU
675      */
676     create_unimplemented_device("csu", FSL_IMX7_CSU_ADDR,
677                                 FSL_IMX7_CSU_SIZE);
678 
679     /*
680      * TZASC
681      */
682     create_unimplemented_device("tzasc", FSL_IMX7_TZASC_ADDR,
683                                 FSL_IMX7_TZASC_SIZE);
684 
685     /*
686      * OCRAM memory
687      */
688     memory_region_init_ram(&s->ocram, NULL, "imx7.ocram",
689                            FSL_IMX7_OCRAM_MEM_SIZE,
690                            &error_abort);
691     memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_MEM_ADDR,
692                                 &s->ocram);
693 
694     /*
695      * OCRAM EPDC memory
696      */
697     memory_region_init_ram(&s->ocram_epdc, NULL, "imx7.ocram_epdc",
698                            FSL_IMX7_OCRAM_EPDC_SIZE,
699                            &error_abort);
700     memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_EPDC_ADDR,
701                                 &s->ocram_epdc);
702 
703     /*
704      * OCRAM PXP memory
705      */
706     memory_region_init_ram(&s->ocram_pxp, NULL, "imx7.ocram_pxp",
707                            FSL_IMX7_OCRAM_PXP_SIZE,
708                            &error_abort);
709     memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_PXP_ADDR,
710                                 &s->ocram_pxp);
711 
712     /*
713      * OCRAM_S memory
714      */
715     memory_region_init_ram(&s->ocram_s, NULL, "imx7.ocram_s",
716                            FSL_IMX7_OCRAM_S_SIZE,
717                            &error_abort);
718     memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_S_ADDR,
719                                 &s->ocram_s);
720 
721     /*
722      * ROM memory
723      */
724     memory_region_init_rom(&s->rom, OBJECT(dev), "imx7.rom",
725                            FSL_IMX7_ROM_SIZE, &error_abort);
726     memory_region_add_subregion(get_system_memory(), FSL_IMX7_ROM_ADDR,
727                                 &s->rom);
728 
729     /*
730      * CAAM memory
731      */
732     memory_region_init_rom(&s->caam, OBJECT(dev), "imx7.caam",
733                            FSL_IMX7_CAAM_MEM_SIZE, &error_abort);
734     memory_region_add_subregion(get_system_memory(), FSL_IMX7_CAAM_MEM_ADDR,
735                                 &s->caam);
736 }
737 
738 static Property fsl_imx7_properties[] = {
739     DEFINE_PROP_UINT32("fec1-phy-num", FslIMX7State, phy_num[0], 0),
740     DEFINE_PROP_UINT32("fec2-phy-num", FslIMX7State, phy_num[1], 1),
741     DEFINE_PROP_BOOL("fec1-phy-connected", FslIMX7State, phy_connected[0],
742                      true),
743     DEFINE_PROP_BOOL("fec2-phy-connected", FslIMX7State, phy_connected[1],
744                      true),
745     DEFINE_PROP_END_OF_LIST(),
746 };
747 
748 static void fsl_imx7_class_init(ObjectClass *oc, void *data)
749 {
750     DeviceClass *dc = DEVICE_CLASS(oc);
751 
752     device_class_set_props(dc, fsl_imx7_properties);
753     dc->realize = fsl_imx7_realize;
754 
755     /* Reason: Uses serial_hds and nd_table in realize() directly */
756     dc->user_creatable = false;
757     dc->desc = "i.MX7 SOC";
758 }
759 
760 static const TypeInfo fsl_imx7_type_info = {
761     .name = TYPE_FSL_IMX7,
762     .parent = TYPE_DEVICE,
763     .instance_size = sizeof(FslIMX7State),
764     .instance_init = fsl_imx7_init,
765     .class_init = fsl_imx7_class_init,
766 };
767 
768 static void fsl_imx7_register_types(void)
769 {
770     type_register_static(&fsl_imx7_type_info);
771 }
772 type_init(fsl_imx7_register_types)
773