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