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