xref: /qemu/hw/arm/fsl-imx7.c (revision fb49b69bf9fd584546c7d946eaeec90941941d25)
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     Object *o;
170     int i;
171     qemu_irq irq;
172     char name[NAME_SIZE];
173     unsigned int smp_cpus = ms->smp.cpus;
174 
175     if (smp_cpus > FSL_IMX7_NUM_CPUS) {
176         error_setg(errp, "%s: Only %d CPUs are supported (%d requested)",
177                    TYPE_FSL_IMX7, FSL_IMX7_NUM_CPUS, smp_cpus);
178         return;
179     }
180 
181     /*
182      * CPUs
183      */
184     for (i = 0; i < smp_cpus; i++) {
185         o = OBJECT(&s->cpu[i]);
186 
187         /* On uniprocessor, the CBAR is set to 0 */
188         if (smp_cpus > 1) {
189             object_property_set_int(o, "reset-cbar", FSL_IMX7_A7MPCORE_ADDR,
190                                     &error_abort);
191         }
192 
193         if (i) {
194             /*
195              * Secondary CPUs start in powered-down state (and can be
196              * powered up via the SRC system reset controller)
197              */
198             object_property_set_bool(o, "start-powered-off", true,
199                                      &error_abort);
200         }
201 
202         qdev_realize(DEVICE(o), NULL, &error_abort);
203     }
204 
205     /*
206      * A7MPCORE
207      */
208     object_property_set_int(OBJECT(&s->a7mpcore), "num-cpu", smp_cpus,
209                             &error_abort);
210     object_property_set_int(OBJECT(&s->a7mpcore), "num-irq",
211                             FSL_IMX7_MAX_IRQ + GIC_INTERNAL, &error_abort);
212 
213     sysbus_realize(SYS_BUS_DEVICE(&s->a7mpcore), &error_abort);
214     sysbus_mmio_map(SYS_BUS_DEVICE(&s->a7mpcore), 0, FSL_IMX7_A7MPCORE_ADDR);
215 
216     for (i = 0; i < smp_cpus; i++) {
217         SysBusDevice *sbd = SYS_BUS_DEVICE(&s->a7mpcore);
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(DEVICE(&s->a7mpcore),
259                                             FSL_IMX7_GPTn_IRQ[i]));
260     }
261 
262     /*
263      * GPIOs
264      */
265     for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
266         static const hwaddr FSL_IMX7_GPIOn_ADDR[FSL_IMX7_NUM_GPIOS] = {
267             FSL_IMX7_GPIO1_ADDR,
268             FSL_IMX7_GPIO2_ADDR,
269             FSL_IMX7_GPIO3_ADDR,
270             FSL_IMX7_GPIO4_ADDR,
271             FSL_IMX7_GPIO5_ADDR,
272             FSL_IMX7_GPIO6_ADDR,
273             FSL_IMX7_GPIO7_ADDR,
274         };
275 
276         static const int FSL_IMX7_GPIOn_LOW_IRQ[FSL_IMX7_NUM_GPIOS] = {
277             FSL_IMX7_GPIO1_LOW_IRQ,
278             FSL_IMX7_GPIO2_LOW_IRQ,
279             FSL_IMX7_GPIO3_LOW_IRQ,
280             FSL_IMX7_GPIO4_LOW_IRQ,
281             FSL_IMX7_GPIO5_LOW_IRQ,
282             FSL_IMX7_GPIO6_LOW_IRQ,
283             FSL_IMX7_GPIO7_LOW_IRQ,
284         };
285 
286         static const int FSL_IMX7_GPIOn_HIGH_IRQ[FSL_IMX7_NUM_GPIOS] = {
287             FSL_IMX7_GPIO1_HIGH_IRQ,
288             FSL_IMX7_GPIO2_HIGH_IRQ,
289             FSL_IMX7_GPIO3_HIGH_IRQ,
290             FSL_IMX7_GPIO4_HIGH_IRQ,
291             FSL_IMX7_GPIO5_HIGH_IRQ,
292             FSL_IMX7_GPIO6_HIGH_IRQ,
293             FSL_IMX7_GPIO7_HIGH_IRQ,
294         };
295 
296         sysbus_realize(SYS_BUS_DEVICE(&s->gpio[i]), &error_abort);
297         sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0,
298                         FSL_IMX7_GPIOn_ADDR[i]);
299 
300         sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0,
301                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
302                                             FSL_IMX7_GPIOn_LOW_IRQ[i]));
303 
304         sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 1,
305                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
306                                             FSL_IMX7_GPIOn_HIGH_IRQ[i]));
307     }
308 
309     /*
310      * IOMUXC and IOMUXC_LPSR
311      */
312     create_unimplemented_device("iomuxc", FSL_IMX7_IOMUXC_ADDR,
313                                 FSL_IMX7_IOMUXC_SIZE);
314     create_unimplemented_device("iomuxc_lspr", FSL_IMX7_IOMUXC_LPSR_ADDR,
315                                 FSL_IMX7_IOMUXC_LPSR_SIZE);
316 
317     /*
318      * CCM
319      */
320     sysbus_realize(SYS_BUS_DEVICE(&s->ccm), &error_abort);
321     sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX7_CCM_ADDR);
322 
323     /*
324      * Analog
325      */
326     sysbus_realize(SYS_BUS_DEVICE(&s->analog), &error_abort);
327     sysbus_mmio_map(SYS_BUS_DEVICE(&s->analog), 0, FSL_IMX7_ANALOG_ADDR);
328 
329     /*
330      * GPCv2
331      */
332     sysbus_realize(SYS_BUS_DEVICE(&s->gpcv2), &error_abort);
333     sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpcv2), 0, FSL_IMX7_GPC_ADDR);
334 
335     /*
336      * ECSPIs
337      */
338     for (i = 0; i < FSL_IMX7_NUM_ECSPIS; i++) {
339         static const hwaddr FSL_IMX7_SPIn_ADDR[FSL_IMX7_NUM_ECSPIS] = {
340             FSL_IMX7_ECSPI1_ADDR,
341             FSL_IMX7_ECSPI2_ADDR,
342             FSL_IMX7_ECSPI3_ADDR,
343             FSL_IMX7_ECSPI4_ADDR,
344         };
345 
346         static const int FSL_IMX7_SPIn_IRQ[FSL_IMX7_NUM_ECSPIS] = {
347             FSL_IMX7_ECSPI1_IRQ,
348             FSL_IMX7_ECSPI2_IRQ,
349             FSL_IMX7_ECSPI3_IRQ,
350             FSL_IMX7_ECSPI4_IRQ,
351         };
352 
353         /* Initialize the SPI */
354         sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), &error_abort);
355         sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0,
356                         FSL_IMX7_SPIn_ADDR[i]);
357         sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0,
358                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
359                                             FSL_IMX7_SPIn_IRQ[i]));
360     }
361 
362     /*
363      * I2Cs
364      */
365     for (i = 0; i < FSL_IMX7_NUM_I2CS; i++) {
366         static const hwaddr FSL_IMX7_I2Cn_ADDR[FSL_IMX7_NUM_I2CS] = {
367             FSL_IMX7_I2C1_ADDR,
368             FSL_IMX7_I2C2_ADDR,
369             FSL_IMX7_I2C3_ADDR,
370             FSL_IMX7_I2C4_ADDR,
371         };
372 
373         static const int FSL_IMX7_I2Cn_IRQ[FSL_IMX7_NUM_I2CS] = {
374             FSL_IMX7_I2C1_IRQ,
375             FSL_IMX7_I2C2_IRQ,
376             FSL_IMX7_I2C3_IRQ,
377             FSL_IMX7_I2C4_IRQ,
378         };
379 
380         sysbus_realize(SYS_BUS_DEVICE(&s->i2c[i]), &error_abort);
381         sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, FSL_IMX7_I2Cn_ADDR[i]);
382 
383         sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
384                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
385                                             FSL_IMX7_I2Cn_IRQ[i]));
386     }
387 
388     /*
389      * UARTs
390      */
391     for (i = 0; i < FSL_IMX7_NUM_UARTS; i++) {
392         static const hwaddr FSL_IMX7_UARTn_ADDR[FSL_IMX7_NUM_UARTS] = {
393             FSL_IMX7_UART1_ADDR,
394             FSL_IMX7_UART2_ADDR,
395             FSL_IMX7_UART3_ADDR,
396             FSL_IMX7_UART4_ADDR,
397             FSL_IMX7_UART5_ADDR,
398             FSL_IMX7_UART6_ADDR,
399             FSL_IMX7_UART7_ADDR,
400         };
401 
402         static const int FSL_IMX7_UARTn_IRQ[FSL_IMX7_NUM_UARTS] = {
403             FSL_IMX7_UART1_IRQ,
404             FSL_IMX7_UART2_IRQ,
405             FSL_IMX7_UART3_IRQ,
406             FSL_IMX7_UART4_IRQ,
407             FSL_IMX7_UART5_IRQ,
408             FSL_IMX7_UART6_IRQ,
409             FSL_IMX7_UART7_IRQ,
410         };
411 
412 
413         qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", serial_hd(i));
414 
415         sysbus_realize(SYS_BUS_DEVICE(&s->uart[i]), &error_abort);
416 
417         sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, FSL_IMX7_UARTn_ADDR[i]);
418 
419         irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_UARTn_IRQ[i]);
420         sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0, irq);
421     }
422 
423     /*
424      * Ethernets
425      *
426      * We must use two loops since phy_connected affects the other interface
427      * and we have to set all properties before calling sysbus_realize().
428      */
429     for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
430         object_property_set_bool(OBJECT(&s->eth[i]), "phy-connected",
431                                  s->phy_connected[i], &error_abort);
432         /*
433          * If the MDIO bus on this controller is not connected, assume the
434          * other controller provides support for it.
435          */
436         if (!s->phy_connected[i]) {
437             object_property_set_link(OBJECT(&s->eth[1 - i]), "phy-consumer",
438                                      OBJECT(&s->eth[i]), &error_abort);
439         }
440     }
441 
442     for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
443         static const hwaddr FSL_IMX7_ENETn_ADDR[FSL_IMX7_NUM_ETHS] = {
444             FSL_IMX7_ENET1_ADDR,
445             FSL_IMX7_ENET2_ADDR,
446         };
447 
448         object_property_set_uint(OBJECT(&s->eth[i]), "phy-num",
449                                  s->phy_num[i], &error_abort);
450         object_property_set_uint(OBJECT(&s->eth[i]), "tx-ring-num",
451                                  FSL_IMX7_ETH_NUM_TX_RINGS, &error_abort);
452         qemu_configure_nic_device(DEVICE(&s->eth[i]), true, NULL);
453         sysbus_realize(SYS_BUS_DEVICE(&s->eth[i]), &error_abort);
454 
455         sysbus_mmio_map(SYS_BUS_DEVICE(&s->eth[i]), 0, FSL_IMX7_ENETn_ADDR[i]);
456 
457         irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_ENET_IRQ(i, 0));
458         sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 0, irq);
459         irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_ENET_IRQ(i, 3));
460         sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 1, irq);
461     }
462 
463     /*
464      * USDHCs
465      */
466     for (i = 0; i < FSL_IMX7_NUM_USDHCS; i++) {
467         static const hwaddr FSL_IMX7_USDHCn_ADDR[FSL_IMX7_NUM_USDHCS] = {
468             FSL_IMX7_USDHC1_ADDR,
469             FSL_IMX7_USDHC2_ADDR,
470             FSL_IMX7_USDHC3_ADDR,
471         };
472 
473         static const int FSL_IMX7_USDHCn_IRQ[FSL_IMX7_NUM_USDHCS] = {
474             FSL_IMX7_USDHC1_IRQ,
475             FSL_IMX7_USDHC2_IRQ,
476             FSL_IMX7_USDHC3_IRQ,
477         };
478 
479         object_property_set_uint(OBJECT(&s->usdhc[i]), "vendor",
480                                  SDHCI_VENDOR_IMX, &error_abort);
481         sysbus_realize(SYS_BUS_DEVICE(&s->usdhc[i]), &error_abort);
482 
483         sysbus_mmio_map(SYS_BUS_DEVICE(&s->usdhc[i]), 0,
484                         FSL_IMX7_USDHCn_ADDR[i]);
485 
486         irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_USDHCn_IRQ[i]);
487         sysbus_connect_irq(SYS_BUS_DEVICE(&s->usdhc[i]), 0, irq);
488     }
489 
490     /*
491      * SNVS
492      */
493     sysbus_realize(SYS_BUS_DEVICE(&s->snvs), &error_abort);
494     sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0, FSL_IMX7_SNVS_HP_ADDR);
495 
496     /*
497      * SRC
498      */
499     sysbus_realize(SYS_BUS_DEVICE(&s->src), &error_abort);
500     sysbus_mmio_map(SYS_BUS_DEVICE(&s->src), 0, FSL_IMX7_SRC_ADDR);
501 
502     /*
503      * Watchdogs
504      */
505     for (i = 0; i < FSL_IMX7_NUM_WDTS; i++) {
506         static const hwaddr FSL_IMX7_WDOGn_ADDR[FSL_IMX7_NUM_WDTS] = {
507             FSL_IMX7_WDOG1_ADDR,
508             FSL_IMX7_WDOG2_ADDR,
509             FSL_IMX7_WDOG3_ADDR,
510             FSL_IMX7_WDOG4_ADDR,
511         };
512         static const int FSL_IMX7_WDOGn_IRQ[FSL_IMX7_NUM_WDTS] = {
513             FSL_IMX7_WDOG1_IRQ,
514             FSL_IMX7_WDOG2_IRQ,
515             FSL_IMX7_WDOG3_IRQ,
516             FSL_IMX7_WDOG4_IRQ,
517         };
518 
519         object_property_set_bool(OBJECT(&s->wdt[i]), "pretimeout-support",
520                                  true, &error_abort);
521         sysbus_realize(SYS_BUS_DEVICE(&s->wdt[i]), &error_abort);
522 
523         sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, FSL_IMX7_WDOGn_ADDR[i]);
524         sysbus_connect_irq(SYS_BUS_DEVICE(&s->wdt[i]), 0,
525                            qdev_get_gpio_in(DEVICE(&s->a7mpcore),
526                                             FSL_IMX7_WDOGn_IRQ[i]));
527     }
528 
529     /*
530      * SDMA
531      */
532     create_unimplemented_device("sdma", FSL_IMX7_SDMA_ADDR, FSL_IMX7_SDMA_SIZE);
533 
534     /*
535      * CAAM
536      */
537     create_unimplemented_device("caam", FSL_IMX7_CAAM_ADDR, FSL_IMX7_CAAM_SIZE);
538 
539     /*
540      * PWMs
541      */
542     for (i = 0; i < FSL_IMX7_NUM_PWMS; i++) {
543         static const hwaddr FSL_IMX7_PWMn_ADDR[FSL_IMX7_NUM_PWMS] = {
544             FSL_IMX7_PWM1_ADDR,
545             FSL_IMX7_PWM2_ADDR,
546             FSL_IMX7_PWM3_ADDR,
547             FSL_IMX7_PWM4_ADDR,
548         };
549 
550         snprintf(name, NAME_SIZE, "pwm%d", i);
551         create_unimplemented_device(name, FSL_IMX7_PWMn_ADDR[i],
552                                     FSL_IMX7_PWMn_SIZE);
553     }
554 
555     /*
556      * CANs
557      */
558     for (i = 0; i < FSL_IMX7_NUM_CANS; i++) {
559         static const hwaddr FSL_IMX7_CANn_ADDR[FSL_IMX7_NUM_CANS] = {
560             FSL_IMX7_CAN1_ADDR,
561             FSL_IMX7_CAN2_ADDR,
562         };
563 
564         snprintf(name, NAME_SIZE, "can%d", i);
565         create_unimplemented_device(name, FSL_IMX7_CANn_ADDR[i],
566                                     FSL_IMX7_CANn_SIZE);
567     }
568 
569     /*
570      * SAIs (Audio SSI (Synchronous Serial Interface))
571      */
572     for (i = 0; i < FSL_IMX7_NUM_SAIS; i++) {
573         static const hwaddr FSL_IMX7_SAIn_ADDR[FSL_IMX7_NUM_SAIS] = {
574             FSL_IMX7_SAI1_ADDR,
575             FSL_IMX7_SAI2_ADDR,
576             FSL_IMX7_SAI3_ADDR,
577         };
578 
579         snprintf(name, NAME_SIZE, "sai%d", i);
580         create_unimplemented_device(name, FSL_IMX7_SAIn_ADDR[i],
581                                     FSL_IMX7_SAIn_SIZE);
582     }
583 
584     /*
585      * OCOTP
586      */
587     create_unimplemented_device("ocotp", FSL_IMX7_OCOTP_ADDR,
588                                 FSL_IMX7_OCOTP_SIZE);
589 
590     /*
591      * GPR
592      */
593     sysbus_realize(SYS_BUS_DEVICE(&s->gpr), &error_abort);
594     sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpr), 0, FSL_IMX7_IOMUXC_GPR_ADDR);
595 
596     /*
597      * PCIE
598      */
599     sysbus_realize(SYS_BUS_DEVICE(&s->pcie), &error_abort);
600     sysbus_mmio_map(SYS_BUS_DEVICE(&s->pcie), 0, FSL_IMX7_PCIE_REG_ADDR);
601 
602     object_property_set_int(OBJECT(&s->pcie4_msi_irq), "num-lines", 2,
603                             &error_abort);
604     qdev_realize(DEVICE(&s->pcie4_msi_irq), NULL, &error_abort);
605 
606     irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTD_MSI_IRQ);
607     qdev_connect_gpio_out(DEVICE(&s->pcie4_msi_irq), 0, irq);
608 
609     irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTA_IRQ);
610     sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 0, irq);
611     irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTB_IRQ);
612     sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 1, irq);
613     irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTC_IRQ);
614     sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 2, irq);
615     irq = qdev_get_gpio_in(DEVICE(&s->pcie4_msi_irq), 0);
616     sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 3, irq);
617     irq = qdev_get_gpio_in(DEVICE(&s->pcie4_msi_irq), 1);
618     sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 4, irq);
619 
620     /*
621      * USBs
622      */
623     for (i = 0; i < FSL_IMX7_NUM_USBS; i++) {
624         static const hwaddr FSL_IMX7_USBMISCn_ADDR[FSL_IMX7_NUM_USBS] = {
625             FSL_IMX7_USBMISC1_ADDR,
626             FSL_IMX7_USBMISC2_ADDR,
627             FSL_IMX7_USBMISC3_ADDR,
628         };
629 
630         static const hwaddr FSL_IMX7_USBn_ADDR[FSL_IMX7_NUM_USBS] = {
631             FSL_IMX7_USB1_ADDR,
632             FSL_IMX7_USB2_ADDR,
633             FSL_IMX7_USB3_ADDR,
634         };
635 
636         static const int FSL_IMX7_USBn_IRQ[FSL_IMX7_NUM_USBS] = {
637             FSL_IMX7_USB1_IRQ,
638             FSL_IMX7_USB2_IRQ,
639             FSL_IMX7_USB3_IRQ,
640         };
641 
642         sysbus_realize(SYS_BUS_DEVICE(&s->usb[i]), &error_abort);
643         sysbus_mmio_map(SYS_BUS_DEVICE(&s->usb[i]), 0,
644                         FSL_IMX7_USBn_ADDR[i]);
645 
646         irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_USBn_IRQ[i]);
647         sysbus_connect_irq(SYS_BUS_DEVICE(&s->usb[i]), 0, irq);
648 
649         snprintf(name, NAME_SIZE, "usbmisc%d", i);
650         create_unimplemented_device(name, FSL_IMX7_USBMISCn_ADDR[i],
651                                     FSL_IMX7_USBMISCn_SIZE);
652     }
653 
654     /*
655      * ADCs
656      */
657     for (i = 0; i < FSL_IMX7_NUM_ADCS; i++) {
658         static const hwaddr FSL_IMX7_ADCn_ADDR[FSL_IMX7_NUM_ADCS] = {
659             FSL_IMX7_ADC1_ADDR,
660             FSL_IMX7_ADC2_ADDR,
661         };
662 
663         snprintf(name, NAME_SIZE, "adc%d", i);
664         create_unimplemented_device(name, FSL_IMX7_ADCn_ADDR[i],
665                                     FSL_IMX7_ADCn_SIZE);
666     }
667 
668     /*
669      * LCD
670      */
671     create_unimplemented_device("lcdif", FSL_IMX7_LCDIF_ADDR,
672                                 FSL_IMX7_LCDIF_SIZE);
673 
674     /*
675      * DMA APBH
676      */
677     create_unimplemented_device("dma-apbh", FSL_IMX7_DMA_APBH_ADDR,
678                                 FSL_IMX7_DMA_APBH_SIZE);
679     /*
680      * PCIe PHY
681      */
682     create_unimplemented_device("pcie-phy", FSL_IMX7_PCIE_PHY_ADDR,
683                                 FSL_IMX7_PCIE_PHY_SIZE);
684 
685     /*
686      * CSU
687      */
688     create_unimplemented_device("csu", FSL_IMX7_CSU_ADDR,
689                                 FSL_IMX7_CSU_SIZE);
690 
691     /*
692      * TZASC
693      */
694     create_unimplemented_device("tzasc", FSL_IMX7_TZASC_ADDR,
695                                 FSL_IMX7_TZASC_SIZE);
696 
697     /*
698      * OCRAM memory
699      */
700     memory_region_init_ram(&s->ocram, NULL, "imx7.ocram",
701                            FSL_IMX7_OCRAM_MEM_SIZE,
702                            &error_abort);
703     memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_MEM_ADDR,
704                                 &s->ocram);
705 
706     /*
707      * OCRAM EPDC memory
708      */
709     memory_region_init_ram(&s->ocram_epdc, NULL, "imx7.ocram_epdc",
710                            FSL_IMX7_OCRAM_EPDC_SIZE,
711                            &error_abort);
712     memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_EPDC_ADDR,
713                                 &s->ocram_epdc);
714 
715     /*
716      * OCRAM PXP memory
717      */
718     memory_region_init_ram(&s->ocram_pxp, NULL, "imx7.ocram_pxp",
719                            FSL_IMX7_OCRAM_PXP_SIZE,
720                            &error_abort);
721     memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_PXP_ADDR,
722                                 &s->ocram_pxp);
723 
724     /*
725      * OCRAM_S memory
726      */
727     memory_region_init_ram(&s->ocram_s, NULL, "imx7.ocram_s",
728                            FSL_IMX7_OCRAM_S_SIZE,
729                            &error_abort);
730     memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_S_ADDR,
731                                 &s->ocram_s);
732 
733     /*
734      * ROM memory
735      */
736     memory_region_init_rom(&s->rom, OBJECT(dev), "imx7.rom",
737                            FSL_IMX7_ROM_SIZE, &error_abort);
738     memory_region_add_subregion(get_system_memory(), FSL_IMX7_ROM_ADDR,
739                                 &s->rom);
740 
741     /*
742      * CAAM memory
743      */
744     memory_region_init_rom(&s->caam, OBJECT(dev), "imx7.caam",
745                            FSL_IMX7_CAAM_MEM_SIZE, &error_abort);
746     memory_region_add_subregion(get_system_memory(), FSL_IMX7_CAAM_MEM_ADDR,
747                                 &s->caam);
748 }
749 
750 static const Property fsl_imx7_properties[] = {
751     DEFINE_PROP_UINT32("fec1-phy-num", FslIMX7State, phy_num[0], 0),
752     DEFINE_PROP_UINT32("fec2-phy-num", FslIMX7State, phy_num[1], 1),
753     DEFINE_PROP_BOOL("fec1-phy-connected", FslIMX7State, phy_connected[0],
754                      true),
755     DEFINE_PROP_BOOL("fec2-phy-connected", FslIMX7State, phy_connected[1],
756                      true),
757 };
758 
759 static void fsl_imx7_class_init(ObjectClass *oc, void *data)
760 {
761     DeviceClass *dc = DEVICE_CLASS(oc);
762 
763     device_class_set_props(dc, fsl_imx7_properties);
764     dc->realize = fsl_imx7_realize;
765 
766     /* Reason: Uses serial_hds and nd_table in realize() directly */
767     dc->user_creatable = false;
768     dc->desc = "i.MX7 SOC";
769 }
770 
771 static const TypeInfo fsl_imx7_type_info = {
772     .name = TYPE_FSL_IMX7,
773     .parent = TYPE_DEVICE,
774     .instance_size = sizeof(FslIMX7State),
775     .instance_init = fsl_imx7_init,
776     .class_init = fsl_imx7_class_init,
777 };
778 
779 static void fsl_imx7_register_types(void)
780 {
781     type_register_static(&fsl_imx7_type_info);
782 }
783 type_init(fsl_imx7_register_types)
784