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