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