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/boards.h" 24 #include "sysemu/sysemu.h" 25 #include "qemu/error-report.h" 26 #include "qemu/module.h" 27 28 #define NAME_SIZE 20 29 30 static void fsl_imx6ul_init(Object *obj) 31 { 32 MachineState *ms = MACHINE(qdev_get_machine()); 33 FslIMX6ULState *s = FSL_IMX6UL(obj); 34 char name[NAME_SIZE]; 35 int i; 36 37 for (i = 0; i < MIN(ms->smp.cpus, FSL_IMX6UL_NUM_CPUS); i++) { 38 snprintf(name, NAME_SIZE, "cpu%d", i); 39 object_initialize_child(obj, name, &s->cpu[i], sizeof(s->cpu[i]), 40 "cortex-a7-" TYPE_ARM_CPU, &error_abort, NULL); 41 } 42 43 /* 44 * A7MPCORE 45 */ 46 sysbus_init_child_obj(obj, "a7mpcore", &s->a7mpcore, sizeof(s->a7mpcore), 47 TYPE_A15MPCORE_PRIV); 48 49 /* 50 * CCM 51 */ 52 sysbus_init_child_obj(obj, "ccm", &s->ccm, sizeof(s->ccm), TYPE_IMX6UL_CCM); 53 54 /* 55 * SRC 56 */ 57 sysbus_init_child_obj(obj, "src", &s->src, sizeof(s->src), TYPE_IMX6_SRC); 58 59 /* 60 * GPCv2 61 */ 62 sysbus_init_child_obj(obj, "gpcv2", &s->gpcv2, sizeof(s->gpcv2), 63 TYPE_IMX_GPCV2); 64 65 /* 66 * SNVS 67 */ 68 sysbus_init_child_obj(obj, "snvs", &s->snvs, sizeof(s->snvs), 69 TYPE_IMX7_SNVS); 70 71 /* 72 * GPR 73 */ 74 sysbus_init_child_obj(obj, "gpr", &s->gpr, sizeof(s->gpr), 75 TYPE_IMX7_GPR); 76 77 /* 78 * GPIOs 1 to 5 79 */ 80 for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) { 81 snprintf(name, NAME_SIZE, "gpio%d", i); 82 sysbus_init_child_obj(obj, name, &s->gpio[i], sizeof(s->gpio[i]), 83 TYPE_IMX_GPIO); 84 } 85 86 /* 87 * GPT 1, 2 88 */ 89 for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) { 90 snprintf(name, NAME_SIZE, "gpt%d", i); 91 sysbus_init_child_obj(obj, name, &s->gpt[i], sizeof(s->gpt[i]), 92 TYPE_IMX7_GPT); 93 } 94 95 /* 96 * EPIT 1, 2 97 */ 98 for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) { 99 snprintf(name, NAME_SIZE, "epit%d", i + 1); 100 sysbus_init_child_obj(obj, name, &s->epit[i], sizeof(s->epit[i]), 101 TYPE_IMX_EPIT); 102 } 103 104 /* 105 * eCSPI 106 */ 107 for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) { 108 snprintf(name, NAME_SIZE, "spi%d", i + 1); 109 sysbus_init_child_obj(obj, name, &s->spi[i], sizeof(s->spi[i]), 110 TYPE_IMX_SPI); 111 } 112 113 /* 114 * I2C 115 */ 116 for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) { 117 snprintf(name, NAME_SIZE, "i2c%d", i + 1); 118 sysbus_init_child_obj(obj, name, &s->i2c[i], sizeof(s->i2c[i]), 119 TYPE_IMX_I2C); 120 } 121 122 /* 123 * UART 124 */ 125 for (i = 0; i < FSL_IMX6UL_NUM_UARTS; i++) { 126 snprintf(name, NAME_SIZE, "uart%d", i); 127 sysbus_init_child_obj(obj, name, &s->uart[i], sizeof(s->uart[i]), 128 TYPE_IMX_SERIAL); 129 } 130 131 /* 132 * Ethernet 133 */ 134 for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) { 135 snprintf(name, NAME_SIZE, "eth%d", i); 136 sysbus_init_child_obj(obj, name, &s->eth[i], sizeof(s->eth[i]), 137 TYPE_IMX_ENET); 138 } 139 140 /* 141 * SDHCI 142 */ 143 for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) { 144 snprintf(name, NAME_SIZE, "usdhc%d", i); 145 sysbus_init_child_obj(obj, name, &s->usdhc[i], sizeof(s->usdhc[i]), 146 TYPE_IMX_USDHC); 147 } 148 149 /* 150 * Watchdog 151 */ 152 for (i = 0; i < FSL_IMX6UL_NUM_WDTS; i++) { 153 snprintf(name, NAME_SIZE, "wdt%d", i); 154 sysbus_init_child_obj(obj, name, &s->wdt[i], sizeof(s->wdt[i]), 155 TYPE_IMX2_WDT); 156 } 157 } 158 159 static void fsl_imx6ul_realize(DeviceState *dev, Error **errp) 160 { 161 MachineState *ms = MACHINE(qdev_get_machine()); 162 FslIMX6ULState *s = FSL_IMX6UL(dev); 163 int i; 164 qemu_irq irq; 165 char name[NAME_SIZE]; 166 unsigned int smp_cpus = ms->smp.cpus; 167 168 if (smp_cpus > FSL_IMX6UL_NUM_CPUS) { 169 error_setg(errp, "%s: Only %d CPUs are supported (%d requested)", 170 TYPE_FSL_IMX6UL, FSL_IMX6UL_NUM_CPUS, smp_cpus); 171 return; 172 } 173 174 for (i = 0; i < smp_cpus; i++) { 175 Object *o = OBJECT(&s->cpu[i]); 176 177 object_property_set_int(o, QEMU_PSCI_CONDUIT_SMC, 178 "psci-conduit", &error_abort); 179 180 /* On uniprocessor, the CBAR is set to 0 */ 181 if (smp_cpus > 1) { 182 object_property_set_int(o, FSL_IMX6UL_A7MPCORE_ADDR, 183 "reset-cbar", &error_abort); 184 } 185 186 if (i) { 187 /* Secondary CPUs start in PSCI powered-down state */ 188 object_property_set_bool(o, true, 189 "start-powered-off", &error_abort); 190 } 191 192 object_property_set_bool(o, true, "realized", &error_abort); 193 } 194 195 /* 196 * A7MPCORE 197 */ 198 object_property_set_int(OBJECT(&s->a7mpcore), smp_cpus, "num-cpu", 199 &error_abort); 200 object_property_set_int(OBJECT(&s->a7mpcore), 201 FSL_IMX6UL_MAX_IRQ + GIC_INTERNAL, 202 "num-irq", &error_abort); 203 object_property_set_bool(OBJECT(&s->a7mpcore), true, "realized", 204 &error_abort); 205 sysbus_mmio_map(SYS_BUS_DEVICE(&s->a7mpcore), 0, FSL_IMX6UL_A7MPCORE_ADDR); 206 207 for (i = 0; i < smp_cpus; i++) { 208 SysBusDevice *sbd = SYS_BUS_DEVICE(&s->a7mpcore); 209 DeviceState *d = DEVICE(qemu_get_cpu(i)); 210 211 irq = qdev_get_gpio_in(d, ARM_CPU_IRQ); 212 sysbus_connect_irq(sbd, i, irq); 213 sysbus_connect_irq(sbd, i + smp_cpus, qdev_get_gpio_in(d, ARM_CPU_FIQ)); 214 sysbus_connect_irq(sbd, i + 2 * smp_cpus, 215 qdev_get_gpio_in(d, ARM_CPU_VIRQ)); 216 sysbus_connect_irq(sbd, i + 3 * smp_cpus, 217 qdev_get_gpio_in(d, ARM_CPU_VFIQ)); 218 } 219 220 /* 221 * A7MPCORE DAP 222 */ 223 create_unimplemented_device("a7mpcore-dap", FSL_IMX6UL_A7MPCORE_DAP_ADDR, 224 0x100000); 225 226 /* 227 * GPT 1, 2 228 */ 229 for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) { 230 static const hwaddr FSL_IMX6UL_GPTn_ADDR[FSL_IMX6UL_NUM_GPTS] = { 231 FSL_IMX6UL_GPT1_ADDR, 232 FSL_IMX6UL_GPT2_ADDR, 233 }; 234 235 static const int FSL_IMX6UL_GPTn_IRQ[FSL_IMX6UL_NUM_GPTS] = { 236 FSL_IMX6UL_GPT1_IRQ, 237 FSL_IMX6UL_GPT2_IRQ, 238 }; 239 240 s->gpt[i].ccm = IMX_CCM(&s->ccm); 241 object_property_set_bool(OBJECT(&s->gpt[i]), true, "realized", 242 &error_abort); 243 244 sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0, 245 FSL_IMX6UL_GPTn_ADDR[i]); 246 247 sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0, 248 qdev_get_gpio_in(DEVICE(&s->a7mpcore), 249 FSL_IMX6UL_GPTn_IRQ[i])); 250 } 251 252 /* 253 * EPIT 1, 2 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 object_property_set_bool(OBJECT(&s->epit[i]), true, "realized", 268 &error_abort); 269 270 sysbus_mmio_map(SYS_BUS_DEVICE(&s->epit[i]), 0, 271 FSL_IMX6UL_EPITn_ADDR[i]); 272 273 sysbus_connect_irq(SYS_BUS_DEVICE(&s->epit[i]), 0, 274 qdev_get_gpio_in(DEVICE(&s->a7mpcore), 275 FSL_IMX6UL_EPITn_IRQ[i])); 276 } 277 278 /* 279 * GPIO 280 */ 281 for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) { 282 static const hwaddr FSL_IMX6UL_GPIOn_ADDR[FSL_IMX6UL_NUM_GPIOS] = { 283 FSL_IMX6UL_GPIO1_ADDR, 284 FSL_IMX6UL_GPIO2_ADDR, 285 FSL_IMX6UL_GPIO3_ADDR, 286 FSL_IMX6UL_GPIO4_ADDR, 287 FSL_IMX6UL_GPIO5_ADDR, 288 }; 289 290 static const int FSL_IMX6UL_GPIOn_LOW_IRQ[FSL_IMX6UL_NUM_GPIOS] = { 291 FSL_IMX6UL_GPIO1_LOW_IRQ, 292 FSL_IMX6UL_GPIO2_LOW_IRQ, 293 FSL_IMX6UL_GPIO3_LOW_IRQ, 294 FSL_IMX6UL_GPIO4_LOW_IRQ, 295 FSL_IMX6UL_GPIO5_LOW_IRQ, 296 }; 297 298 static const int FSL_IMX6UL_GPIOn_HIGH_IRQ[FSL_IMX6UL_NUM_GPIOS] = { 299 FSL_IMX6UL_GPIO1_HIGH_IRQ, 300 FSL_IMX6UL_GPIO2_HIGH_IRQ, 301 FSL_IMX6UL_GPIO3_HIGH_IRQ, 302 FSL_IMX6UL_GPIO4_HIGH_IRQ, 303 FSL_IMX6UL_GPIO5_HIGH_IRQ, 304 }; 305 306 object_property_set_bool(OBJECT(&s->gpio[i]), true, "realized", 307 &error_abort); 308 309 sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0, 310 FSL_IMX6UL_GPIOn_ADDR[i]); 311 312 sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0, 313 qdev_get_gpio_in(DEVICE(&s->a7mpcore), 314 FSL_IMX6UL_GPIOn_LOW_IRQ[i])); 315 316 sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 1, 317 qdev_get_gpio_in(DEVICE(&s->a7mpcore), 318 FSL_IMX6UL_GPIOn_HIGH_IRQ[i])); 319 } 320 321 /* 322 * IOMUXC and IOMUXC_GPR 323 */ 324 for (i = 0; i < 1; i++) { 325 static const hwaddr FSL_IMX6UL_IOMUXCn_ADDR[FSL_IMX6UL_NUM_IOMUXCS] = { 326 FSL_IMX6UL_IOMUXC_ADDR, 327 FSL_IMX6UL_IOMUXC_GPR_ADDR, 328 }; 329 330 snprintf(name, NAME_SIZE, "iomuxc%d", i); 331 create_unimplemented_device(name, FSL_IMX6UL_IOMUXCn_ADDR[i], 0x4000); 332 } 333 334 /* 335 * CCM 336 */ 337 object_property_set_bool(OBJECT(&s->ccm), true, "realized", &error_abort); 338 sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX6UL_CCM_ADDR); 339 340 /* 341 * SRC 342 */ 343 object_property_set_bool(OBJECT(&s->src), true, "realized", &error_abort); 344 sysbus_mmio_map(SYS_BUS_DEVICE(&s->src), 0, FSL_IMX6UL_SRC_ADDR); 345 346 /* 347 * GPCv2 348 */ 349 object_property_set_bool(OBJECT(&s->gpcv2), true, 350 "realized", &error_abort); 351 sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpcv2), 0, FSL_IMX6UL_GPC_ADDR); 352 353 /* Initialize all ECSPI */ 354 for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) { 355 static const hwaddr FSL_IMX6UL_SPIn_ADDR[FSL_IMX6UL_NUM_ECSPIS] = { 356 FSL_IMX6UL_ECSPI1_ADDR, 357 FSL_IMX6UL_ECSPI2_ADDR, 358 FSL_IMX6UL_ECSPI3_ADDR, 359 FSL_IMX6UL_ECSPI4_ADDR, 360 }; 361 362 static const int FSL_IMX6UL_SPIn_IRQ[FSL_IMX6UL_NUM_ECSPIS] = { 363 FSL_IMX6UL_ECSPI1_IRQ, 364 FSL_IMX6UL_ECSPI2_IRQ, 365 FSL_IMX6UL_ECSPI3_IRQ, 366 FSL_IMX6UL_ECSPI4_IRQ, 367 }; 368 369 /* Initialize the SPI */ 370 object_property_set_bool(OBJECT(&s->spi[i]), true, "realized", 371 &error_abort); 372 373 sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, 374 FSL_IMX6UL_SPIn_ADDR[i]); 375 376 sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0, 377 qdev_get_gpio_in(DEVICE(&s->a7mpcore), 378 FSL_IMX6UL_SPIn_IRQ[i])); 379 } 380 381 /* 382 * I2C 383 */ 384 for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) { 385 static const hwaddr FSL_IMX6UL_I2Cn_ADDR[FSL_IMX6UL_NUM_I2CS] = { 386 FSL_IMX6UL_I2C1_ADDR, 387 FSL_IMX6UL_I2C2_ADDR, 388 FSL_IMX6UL_I2C3_ADDR, 389 FSL_IMX6UL_I2C4_ADDR, 390 }; 391 392 static const int FSL_IMX6UL_I2Cn_IRQ[FSL_IMX6UL_NUM_I2CS] = { 393 FSL_IMX6UL_I2C1_IRQ, 394 FSL_IMX6UL_I2C2_IRQ, 395 FSL_IMX6UL_I2C3_IRQ, 396 FSL_IMX6UL_I2C4_IRQ, 397 }; 398 399 object_property_set_bool(OBJECT(&s->i2c[i]), true, "realized", 400 &error_abort); 401 sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, FSL_IMX6UL_I2Cn_ADDR[i]); 402 403 sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0, 404 qdev_get_gpio_in(DEVICE(&s->a7mpcore), 405 FSL_IMX6UL_I2Cn_IRQ[i])); 406 } 407 408 /* 409 * UART 410 */ 411 for (i = 0; i < FSL_IMX6UL_NUM_UARTS; i++) { 412 static const hwaddr FSL_IMX6UL_UARTn_ADDR[FSL_IMX6UL_NUM_UARTS] = { 413 FSL_IMX6UL_UART1_ADDR, 414 FSL_IMX6UL_UART2_ADDR, 415 FSL_IMX6UL_UART3_ADDR, 416 FSL_IMX6UL_UART4_ADDR, 417 FSL_IMX6UL_UART5_ADDR, 418 FSL_IMX6UL_UART6_ADDR, 419 FSL_IMX6UL_UART7_ADDR, 420 FSL_IMX6UL_UART8_ADDR, 421 }; 422 423 static const int FSL_IMX6UL_UARTn_IRQ[FSL_IMX6UL_NUM_UARTS] = { 424 FSL_IMX6UL_UART1_IRQ, 425 FSL_IMX6UL_UART2_IRQ, 426 FSL_IMX6UL_UART3_IRQ, 427 FSL_IMX6UL_UART4_IRQ, 428 FSL_IMX6UL_UART5_IRQ, 429 FSL_IMX6UL_UART6_IRQ, 430 FSL_IMX6UL_UART7_IRQ, 431 FSL_IMX6UL_UART8_IRQ, 432 }; 433 434 qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", serial_hd(i)); 435 436 object_property_set_bool(OBJECT(&s->uart[i]), true, "realized", 437 &error_abort); 438 439 sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, 440 FSL_IMX6UL_UARTn_ADDR[i]); 441 442 sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0, 443 qdev_get_gpio_in(DEVICE(&s->a7mpcore), 444 FSL_IMX6UL_UARTn_IRQ[i])); 445 } 446 447 /* 448 * Ethernet 449 */ 450 for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) { 451 static const hwaddr FSL_IMX6UL_ENETn_ADDR[FSL_IMX6UL_NUM_ETHS] = { 452 FSL_IMX6UL_ENET1_ADDR, 453 FSL_IMX6UL_ENET2_ADDR, 454 }; 455 456 static const int FSL_IMX6UL_ENETn_IRQ[FSL_IMX6UL_NUM_ETHS] = { 457 FSL_IMX6UL_ENET1_IRQ, 458 FSL_IMX6UL_ENET2_IRQ, 459 }; 460 461 static const int FSL_IMX6UL_ENETn_TIMER_IRQ[FSL_IMX6UL_NUM_ETHS] = { 462 FSL_IMX6UL_ENET1_TIMER_IRQ, 463 FSL_IMX6UL_ENET2_TIMER_IRQ, 464 }; 465 466 object_property_set_uint(OBJECT(&s->eth[i]), 467 FSL_IMX6UL_ETH_NUM_TX_RINGS, 468 "tx-ring-num", &error_abort); 469 qdev_set_nic_properties(DEVICE(&s->eth[i]), &nd_table[i]); 470 object_property_set_bool(OBJECT(&s->eth[i]), true, "realized", 471 &error_abort); 472 473 sysbus_mmio_map(SYS_BUS_DEVICE(&s->eth[i]), 0, 474 FSL_IMX6UL_ENETn_ADDR[i]); 475 476 sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 0, 477 qdev_get_gpio_in(DEVICE(&s->a7mpcore), 478 FSL_IMX6UL_ENETn_IRQ[i])); 479 480 sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 1, 481 qdev_get_gpio_in(DEVICE(&s->a7mpcore), 482 FSL_IMX6UL_ENETn_TIMER_IRQ[i])); 483 } 484 485 /* 486 * USDHC 487 */ 488 for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) { 489 static const hwaddr FSL_IMX6UL_USDHCn_ADDR[FSL_IMX6UL_NUM_USDHCS] = { 490 FSL_IMX6UL_USDHC1_ADDR, 491 FSL_IMX6UL_USDHC2_ADDR, 492 }; 493 494 static const int FSL_IMX6UL_USDHCn_IRQ[FSL_IMX6UL_NUM_USDHCS] = { 495 FSL_IMX6UL_USDHC1_IRQ, 496 FSL_IMX6UL_USDHC2_IRQ, 497 }; 498 499 object_property_set_bool(OBJECT(&s->usdhc[i]), true, "realized", 500 &error_abort); 501 502 sysbus_mmio_map(SYS_BUS_DEVICE(&s->usdhc[i]), 0, 503 FSL_IMX6UL_USDHCn_ADDR[i]); 504 505 sysbus_connect_irq(SYS_BUS_DEVICE(&s->usdhc[i]), 0, 506 qdev_get_gpio_in(DEVICE(&s->a7mpcore), 507 FSL_IMX6UL_USDHCn_IRQ[i])); 508 } 509 510 /* 511 * SNVS 512 */ 513 object_property_set_bool(OBJECT(&s->snvs), true, "realized", &error_abort); 514 sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0, FSL_IMX6UL_SNVS_HP_ADDR); 515 516 /* 517 * Watchdog 518 */ 519 for (i = 0; i < FSL_IMX6UL_NUM_WDTS; i++) { 520 static const hwaddr FSL_IMX6UL_WDOGn_ADDR[FSL_IMX6UL_NUM_WDTS] = { 521 FSL_IMX6UL_WDOG1_ADDR, 522 FSL_IMX6UL_WDOG2_ADDR, 523 FSL_IMX6UL_WDOG3_ADDR, 524 }; 525 526 object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", 527 &error_abort); 528 529 sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, 530 FSL_IMX6UL_WDOGn_ADDR[i]); 531 } 532 533 /* 534 * GPR 535 */ 536 object_property_set_bool(OBJECT(&s->gpr), true, "realized", 537 &error_abort); 538 sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpr), 0, FSL_IMX6UL_IOMUXC_GPR_ADDR); 539 540 /* 541 * SDMA 542 */ 543 create_unimplemented_device("sdma", FSL_IMX6UL_SDMA_ADDR, 0x4000); 544 545 /* 546 * APHB_DMA 547 */ 548 create_unimplemented_device("aphb_dma", FSL_IMX6UL_APBH_DMA_ADDR, 549 FSL_IMX6UL_APBH_DMA_SIZE); 550 551 /* 552 * ADCs 553 */ 554 for (i = 0; i < FSL_IMX6UL_NUM_ADCS; i++) { 555 static const hwaddr FSL_IMX6UL_ADCn_ADDR[FSL_IMX6UL_NUM_ADCS] = { 556 FSL_IMX6UL_ADC1_ADDR, 557 FSL_IMX6UL_ADC2_ADDR, 558 }; 559 560 snprintf(name, NAME_SIZE, "adc%d", i); 561 create_unimplemented_device(name, FSL_IMX6UL_ADCn_ADDR[i], 0x4000); 562 } 563 564 /* 565 * LCD 566 */ 567 create_unimplemented_device("lcdif", FSL_IMX6UL_LCDIF_ADDR, 0x4000); 568 569 /* 570 * ROM memory 571 */ 572 memory_region_init_rom(&s->rom, NULL, "imx6ul.rom", 573 FSL_IMX6UL_ROM_SIZE, &error_abort); 574 memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_ROM_ADDR, 575 &s->rom); 576 577 /* 578 * CAAM memory 579 */ 580 memory_region_init_rom(&s->caam, NULL, "imx6ul.caam", 581 FSL_IMX6UL_CAAM_MEM_SIZE, &error_abort); 582 memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_CAAM_MEM_ADDR, 583 &s->caam); 584 585 /* 586 * OCRAM memory 587 */ 588 memory_region_init_ram(&s->ocram, NULL, "imx6ul.ocram", 589 FSL_IMX6UL_OCRAM_MEM_SIZE, 590 &error_abort); 591 memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_OCRAM_MEM_ADDR, 592 &s->ocram); 593 594 /* 595 * internal OCRAM (128 KB) is aliased over 512 KB 596 */ 597 memory_region_init_alias(&s->ocram_alias, NULL, "imx6ul.ocram_alias", 598 &s->ocram, 0, FSL_IMX6UL_OCRAM_ALIAS_SIZE); 599 memory_region_add_subregion(get_system_memory(), 600 FSL_IMX6UL_OCRAM_ALIAS_ADDR, &s->ocram_alias); 601 } 602 603 static void fsl_imx6ul_class_init(ObjectClass *oc, void *data) 604 { 605 DeviceClass *dc = DEVICE_CLASS(oc); 606 607 dc->realize = fsl_imx6ul_realize; 608 dc->desc = "i.MX6UL SOC"; 609 /* Reason: Uses serial_hds and nd_table in realize() directly */ 610 dc->user_creatable = false; 611 } 612 613 static const TypeInfo fsl_imx6ul_type_info = { 614 .name = TYPE_FSL_IMX6UL, 615 .parent = TYPE_DEVICE, 616 .instance_size = sizeof(FslIMX6ULState), 617 .instance_init = fsl_imx6ul_init, 618 .class_init = fsl_imx6ul_class_init, 619 }; 620 621 static void fsl_imx6ul_register_types(void) 622 { 623 type_register_static(&fsl_imx6ul_type_info); 624 } 625 type_init(fsl_imx6ul_register_types) 626