TO BE BACKED OUT!!!!!

Change-Id: Iaee65038a92c82372e51681c4f30b274e9c94eab
diff --git a/system/dev/board/imx8mevk/imx8mevk-gpio.c b/system/dev/board/imx8mevk/imx8mevk-gpio.c
new file mode 100644
index 0000000..7764df2
--- /dev/null
+++ b/system/dev/board/imx8mevk/imx8mevk-gpio.c
@@ -0,0 +1,140 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <ddk/debug.h>
+#include <ddk/device.h>
+#include <ddk/protocol/platform-bus.h>
+#include <ddk/protocol/platform-defs.h>
+
+#include <soc/imx8m/imx8m.h>
+#include <soc/imx8m/imx8m-hw.h>
+#include <soc/imx8m/imx8m-iomux.h>
+#include <soc/imx8m/imx8m-gpio.h>
+#include <limits.h>
+
+#include "imx8mevk.h"
+
+// uncomment to disable LED blinky test
+#define GPIO_TEST 1
+
+static const pbus_mmio_t gpio_mmios[] = {
+    {
+        .base = IMX8M_AIPS_GPIO1_BASE,
+        .length = IMX8M_AIPS_LENGTH,
+    },
+    {
+        .base = IMX8M_AIPS_GPIO2_BASE,
+        .length = IMX8M_AIPS_LENGTH,
+    },
+    {
+        .base = IMX8M_AIPS_GPIO3_BASE,
+        .length = IMX8M_AIPS_LENGTH,
+    },
+    {
+        .base = IMX8M_AIPS_GPIO4_BASE,
+        .length = IMX8M_AIPS_LENGTH,
+    },
+    {
+        .base = IMX8M_AIPS_GPIO5_BASE,
+        .length = IMX8M_AIPS_LENGTH,
+    },
+};
+
+static const pbus_irq_t gpio_irqs[] = {
+    {
+        .irq = IMX8M_A53_INTR_GPIO1_INT_COMB_0_15,
+        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
+    },
+    {
+        .irq = IMX8M_A53_INTR_GPIO1_INT_COMP_16_31,
+        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
+    },
+    {
+        .irq = IMX8M_A53_INTR_GPIO2_INT_COMB_0_15,
+        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
+    },
+    {
+        .irq = IMX8M_A53_INTR_GPIO2_INT_COMP_16_31,
+        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
+    },
+    {
+        .irq = IMX8M_A53_INTR_GPIO3_INT_COMB_0_15,
+        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
+    },
+    {
+        .irq = IMX8M_A53_INTR_GPIO3_INT_COMP_16_31,
+        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
+    },
+    {
+        .irq = IMX8M_A53_INTR_GPIO4_INT_COMB_0_15,
+        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
+    },
+    {
+        .irq = IMX8M_A53_INTR_GPIO4_INT_COMP_16_31,
+        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
+    },
+    {
+        .irq = IMX8M_A53_INTR_GPIO5_INT_COMB_0_15,
+        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
+    },
+    {
+        .irq = IMX8M_A53_INTR_GPIO5_INT_COMP_16_31,
+        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
+    },
+};
+
+static pbus_dev_t gpio_dev = {
+    .name = "gpio",
+    .vid = PDEV_VID_NXP,
+    .pid = PDEV_PID_IMX8MEVK,
+    .did = PDEV_DID_IMX_GPIO,
+    .mmios = gpio_mmios,
+    .mmio_count = countof(gpio_mmios),
+    .irqs = gpio_irqs,
+    .irq_count = countof(gpio_irqs),
+};
+
+zx_status_t imx8m_gpio_init(imx8mevk_bus_t* bus) {
+    zx_status_t status = pbus_device_add(&bus->pbus, &gpio_dev, PDEV_ADD_PBUS_DEVHOST);
+    if (status != ZX_OK) {
+        zxlogf(ERROR, "%s: pbus_device_add failed %d\n", __FUNCTION__, status);
+        return status;
+    }
+
+    status = pbus_wait_protocol(&bus->pbus, ZX_PROTOCOL_GPIO);
+    if (status != ZX_OK) {
+        zxlogf(ERROR, "%s: pbus_wait_protocol failed %d\n", __FUNCTION__, status);
+        return status;
+    }
+
+    status = device_get_protocol(bus->parent, ZX_PROTOCOL_GPIO, &bus->gpio);
+    if (status != ZX_OK) {
+        zxlogf(ERROR, "%s: device_get_protocol failed %d\n", __FUNCTION__, status);
+        return status;
+    }
+
+#if GPIO_TEST
+    const pbus_gpio_t gpio_test_gpios[] = {
+        {
+            // PWR_LED
+            .gpio = IMX_GPIO_PIN(1, 13), // GPIO blocks nums are 1-based
+        },
+    };
+
+    const pbus_dev_t gpio_test_dev = {
+        .name = "imx8mevk-gpio-test",
+        .vid = PDEV_VID_GENERIC,
+        .pid = PDEV_PID_GENERIC,
+        .did = PDEV_DID_GPIO_TEST,
+        .gpios = gpio_test_gpios,
+        .gpio_count = countof(gpio_test_gpios),
+    };
+    if ((status = pbus_device_add(&bus->pbus, &gpio_test_dev, 0)) != ZX_OK) {
+        zxlogf(ERROR, "%s: Could not add gpio_test_dev %d\n", __FUNCTION__, status);
+        return status;
+    }
+#endif
+
+    return ZX_OK;
+}
\ No newline at end of file
diff --git a/system/dev/board/imx8mevk/imx8mevk.c b/system/dev/board/imx8mevk/imx8mevk.c
new file mode 100644
index 0000000..3405162
--- /dev/null
+++ b/system/dev/board/imx8mevk/imx8mevk.c
@@ -0,0 +1,159 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <assert.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <threads.h>
+#include <unistd.h>
+
+#include <ddk/binding.h>
+#include <ddk/debug.h>
+#include <ddk/device.h>
+#include <ddk/driver.h>
+#include <ddk/protocol/platform-defs.h>
+#include <hw/reg.h>
+
+#include <soc/imx8m/imx8m.h>
+#include <soc/imx8m/imx8m-hw.h>
+#include <soc/imx8m/imx8m-iomux.h>
+
+#include <zircon/assert.h>
+#include <zircon/process.h>
+#include <zircon/syscalls.h>
+#include <zircon/threads.h>
+
+#include "imx8mevk.h"
+
+/* iMX8M EVK Pin Mux Table TODO: Add all supported peripherals on EVK board */
+iomux_cfg_struct imx8mevk_pinmux[] = {
+    // UART1 RX
+    MAKE_PIN_CFG_UART(0, SW_MUX_CTL_PAD_UART1_RXD,
+                            SW_PAD_CTL_PAD_UART1_RXD,
+                            UART1_RXD_SELECT_INPUT),
+    // UART1 TX
+    MAKE_PIN_CFG_UART(0, SW_MUX_CTL_PAD_UART1_TXD,
+                            SW_PAD_CTL_PAD_UART1_TXD,
+                            0x000ULL),
+
+    // PWR_LED (used for GPIO Driver)
+    MAKE_PIN_CFG_DEFAULT(0,  SW_MUX_CTL_PAD_GPIO1_IO13),
+};
+
+static void imx8mevk_bus_release(void* ctx) {
+    imx8mevk_bus_t* bus = ctx;
+    free(bus);
+}
+
+static zx_protocol_device_t imx8mevk_bus_device_protocol = {
+    .version = DEVICE_OPS_VERSION,
+    .release = imx8mevk_bus_release,
+};
+
+static int imx8mevk_start_thread(void* arg) {
+    zx_status_t status;
+    imx8mevk_bus_t* bus = arg;
+
+    // TODO: Power and Clocks
+
+    // Pinmux
+    status = imx8m_config_pin(bus->imx8m, imx8mevk_pinmux,
+                                sizeof(imx8mevk_pinmux)/sizeof(imx8mevk_pinmux[0]));
+
+
+    if ((status = imx8m_gpio_init(bus)) != ZX_OK) {
+        zxlogf(ERROR, "%s: failed %d\n", __FUNCTION__, status);
+        goto fail;
+    }
+
+    return ZX_OK;
+
+fail:
+    zxlogf(ERROR, "aml_start_thread failed, not all devices have been initialized\n");
+    return status;
+}
+
+static zx_status_t imx8mevk_bus_bind(void* ctx, zx_device_t* parent)
+{
+
+    imx8mevk_bus_t* bus = calloc(1, sizeof(imx8mevk_bus_t));
+    if (!bus) {
+        return ZX_ERR_NO_MEMORY;
+    }
+    bus->parent = parent;
+
+    zx_status_t status = device_get_protocol(parent, ZX_PROTOCOL_PLATFORM_BUS, &bus->pbus);
+    if (status != ZX_OK) {
+        goto fail;
+    }
+
+    // get default BTI from the dummy IOMMU implementation in the platform bus
+    status = device_get_protocol(parent, ZX_PROTOCOL_IOMMU, &bus->iommu);
+    if (status != ZX_OK) {
+        zxlogf(ERROR, "%s: Could not get ZX_PROTOCOL_IOMMU\n", __FUNCTION__);
+        goto fail;
+    }
+
+    status = iommu_get_bti(&bus->iommu, 0, BTI_BOARD, &bus->bti_handle);
+    if (status != ZX_OK) {
+        zxlogf(ERROR, "%s: iommu_get_bti failed %d\n", __FUNCTION__, status);
+        goto fail;
+    }
+
+    zx_handle_t resource = get_root_resource();
+    status = imx8m_init(resource, bus->bti_handle, &bus->imx8m);
+    if (status != ZX_OK) {
+        zxlogf(ERROR, "%s: imx8m_init failed %d\n", __FUNCTION__, status);
+        goto fail;
+    }
+
+    const char* board_name = pbus_get_board_name(&bus->pbus);
+    if (!strcmp(board_name, "imx8mevk")) {
+        bus->soc_pid = PDEV_VID_NXP;
+    } else {
+        zxlogf(ERROR, "%s: Invalid/Unsupported board (%s)\n", __FUNCTION__, board_name);
+        goto fail;
+    }
+
+    device_add_args_t args = {
+        .version = DEVICE_ADD_ARGS_VERSION,
+        .name = "imx8mevk",
+        .ctx = bus,
+        .ops = &imx8mevk_bus_device_protocol,
+        .flags = DEVICE_ADD_NON_BINDABLE,
+    };
+
+    status = device_add(parent, &args, NULL);
+    if (status != ZX_OK) {
+        goto fail;
+    }
+
+    thrd_t t;
+    int thrd_rc = thrd_create_with_name(&t, imx8mevk_start_thread, bus, "imx8mevk_start_thread");
+    if (thrd_rc != thrd_success) {
+        status = thrd_status_to_zx_status(thrd_rc);
+        goto fail;
+    }
+
+    return ZX_OK;
+
+fail:
+    zxlogf(ERROR, "%s failed. %d\n", __FUNCTION__, status);
+    imx8mevk_bus_release(bus);
+    return status;
+}
+
+static zx_driver_ops_t imx8mevk_bus_driver_ops = {
+    .version = DRIVER_OPS_VERSION,
+    .bind = imx8mevk_bus_bind,
+};
+
+ZIRCON_DRIVER_BEGIN(vim_bus, imx8mevk_bus_driver_ops, "zircon", "0.1", 4)
+    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PLATFORM_BUS),
+    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_NXP),
+    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_PID, PDEV_PID_IMX8MEVK),
+ZIRCON_DRIVER_END(vim_bus)
diff --git a/system/dev/board/imx8mevk/imx8mevk.h b/system/dev/board/imx8mevk/imx8mevk.h
new file mode 100644
index 0000000..fc8541a
--- /dev/null
+++ b/system/dev/board/imx8mevk/imx8mevk.h
@@ -0,0 +1,34 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#pragma once
+
+#include <ddk/device.h>
+#include <ddk/io-buffer.h>
+#include <ddk/protocol/gpio.h>
+#include <ddk/protocol/i2c.h>
+#include <ddk/protocol/iommu.h>
+#include <ddk/protocol/platform-bus.h>
+#include <ddk/protocol/serial.h>
+
+// BTI IDs for our devices
+enum
+{
+    BTI_BOARD,
+    BTI_IOMUX,
+};
+
+typedef struct {
+    platform_bus_protocol_t     pbus;
+    zx_device_t*                parent;
+    iommu_protocol_t            iommu;
+    gpio_protocol_t             gpio;
+    zx_handle_t                 bti_handle;
+    imx8m_t*                    imx8m;
+    uint32_t                    soc_pid;
+
+} imx8mevk_bus_t;
+
+
+zx_status_t imx8m_gpio_init(imx8mevk_bus_t* bus);
\ No newline at end of file
diff --git a/system/dev/board/imx8mevk/rules.mk b/system/dev/board/imx8mevk/rules.mk
new file mode 100644
index 0000000..ee3bd20
--- /dev/null
+++ b/system/dev/board/imx8mevk/rules.mk
@@ -0,0 +1,28 @@
+# Copyright 2018 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+MODULE_TYPE := driver
+
+MODULE_SRCS += \
+    $(LOCAL_DIR)/imx8mevk.c \
+    $(LOCAL_DIR)/imx8mevk-gpio.c \
+
+MODULE_STATIC_LIBS := \
+    system/dev/soc/imx8m \
+    system/ulib/ddk \
+    system/ulib/sync \
+
+MODULE_LIBS := \
+    system/ulib/driver \
+    system/ulib/c \
+    system/ulib/zircon
+
+MODULE_HEADER_DEPS := \
+    system/dev/soc/imx8m
+
+include make/module.mk
diff --git a/system/dev/gpio/imx8/imx8-gpio.c b/system/dev/gpio/imx8/imx8-gpio.c
new file mode 100644
index 0000000..0a8cdd8
--- /dev/null
+++ b/system/dev/gpio/imx8/imx8-gpio.c
@@ -0,0 +1,209 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdint.h>
+#include <threads.h>
+
+#include <bits/limits.h>
+#include <ddk/binding.h>
+#include <ddk/debug.h>
+#include <ddk/device.h>
+#include <ddk/protocol/gpio.h>
+#include <ddk/protocol/platform-bus.h>
+#include <ddk/protocol/platform-defs.h>
+#include <ddk/protocol/platform-device.h>
+
+#include <soc/imx8m/imx8m.h>
+#include <soc/imx8m/imx8m-hw.h>
+#include <soc/imx8m/imx8m-iomux.h>
+#include <soc/imx8m/imx8m-gpio.h>
+#include <hw/reg.h>
+#include <zircon/assert.h>
+#include <zircon/types.h>
+
+typedef struct {
+    platform_device_protocol_t  pdev;
+    platform_bus_protocol_t     pbus;
+    gpio_protocol_t             gpio;
+    zx_device_t*                zxdev;
+    io_buffer_t                 mmios[IMX_GPIO_BLOCKS];
+    mtx_t                       lock[IMX_GPIO_BLOCKS];
+} imx8_gpio_t;
+
+
+static zx_status_t imx8_gpio_config(void* ctx, uint32_t pin, uint32_t flags) {
+    uint32_t gpio_block;
+    uint32_t gpio_pin;
+    uint32_t regVal;
+    imx8_gpio_t* gpio = ctx;
+
+    gpio_block = IMX_NUM_TO_BLOCK(pin);
+    gpio_pin = IMX_NUM_TO_BIT(pin);
+
+    if (gpio_block >= IMX_GPIO_BLOCKS || gpio_pin >= 32) {
+        zxlogf(ERROR, "%s: Invalid GPIO pin (pin = %d Block = %d, Offset = %d)\n",
+            __FUNCTION__, pin, gpio_block, gpio_pin);
+        return ZX_ERR_INVALID_ARGS;
+    }
+
+    mtx_lock(&gpio->lock[gpio_block]);
+    volatile uint8_t* reg = (volatile uint8_t*)io_buffer_virt(&gpio->mmios[gpio_block]);
+    regVal = readl(reg + IMX_GPIO_GDIR);
+    regVal &= ~(1 << gpio_pin);
+    if (flags & GPIO_DIR_OUT) {
+        regVal |= (GPIO_OUTPUT << gpio_pin);
+    } else {
+        regVal |= (GPIO_INPUT << gpio_pin);
+    }
+    writel(regVal, reg + IMX_GPIO_GDIR);
+    mtx_unlock(&gpio->lock[gpio_block]);
+    return ZX_OK;
+}
+
+
+static zx_status_t imx8_gpio_read(void* ctx, uint32_t pin, uint8_t* out_value) {
+    uint32_t gpio_block;
+    uint32_t gpio_pin;
+    uint32_t regVal;
+    imx8_gpio_t* gpio = ctx;
+
+    gpio_block = IMX_NUM_TO_BLOCK(pin);
+    gpio_pin = IMX_NUM_TO_BIT(pin);
+
+    if (gpio_block >= IMX_GPIO_BLOCKS || gpio_pin >= 32) {
+        zxlogf(ERROR, "%s: Invalid GPIO pin (pin = %d Block = %d, Offset = %d)\n",
+            __FUNCTION__, pin, gpio_block, gpio_pin);
+        return ZX_ERR_INVALID_ARGS;
+    }
+
+    mtx_lock(&gpio->lock[gpio_block]);
+    volatile uint8_t* reg = (volatile uint8_t*)io_buffer_virt(&gpio->mmios[gpio_block]);
+    regVal = readl(reg + IMX_GPIO_DR);
+    regVal >>= (gpio_pin);
+    regVal &= 1;
+    *out_value = regVal;
+    mtx_unlock(&gpio->lock[gpio_block]);
+
+    return ZX_OK;
+}
+
+static zx_status_t imx8_gpio_write(void* ctx, uint32_t pin, uint8_t value) {
+    uint32_t gpio_block;
+    uint32_t gpio_pin;
+    uint32_t regVal;
+    imx8_gpio_t* gpio = ctx;
+
+    gpio_block = IMX_NUM_TO_BLOCK(pin);
+    gpio_pin = IMX_NUM_TO_BIT(pin);
+    if (gpio_block >= IMX_GPIO_BLOCKS || gpio_pin >= 32) {
+        zxlogf(ERROR, "%s: Invalid GPIO pin (pin = %d Block = %d, Offset = %d)\n",
+            __FUNCTION__, pin, gpio_block, gpio_pin);
+        return ZX_ERR_INVALID_ARGS;
+    }
+
+    mtx_lock(&gpio->lock[gpio_block]);
+    volatile uint8_t* reg = (volatile uint8_t*)io_buffer_virt(&gpio->mmios[gpio_block]);
+    regVal = readl(reg + IMX_GPIO_DR);
+    regVal &= ~(1 << gpio_pin);
+    regVal |= (value << gpio_pin);
+    writel(regVal, reg + IMX_GPIO_DR);
+    mtx_unlock(&gpio->lock[gpio_block]);
+
+
+    return ZX_OK;
+}
+
+static gpio_protocol_ops_t gpio_ops = {
+    .config = imx8_gpio_config,
+    .read = imx8_gpio_read,
+    .write = imx8_gpio_write,
+};
+
+static void imx8_gpio_release(void* ctx)
+{
+    unsigned i;
+    imx8_gpio_t* gpio = ctx;
+
+    for (i = 0; i < countof(gpio->mmios); i++) {
+        io_buffer_release(&gpio->mmios[i]);
+    }
+
+    free(gpio);
+}
+
+static zx_protocol_device_t gpio_device_proto = {
+    .version = DEVICE_OPS_VERSION,
+    .release = imx8_gpio_release,
+};
+
+static zx_status_t imx8_gpio_bind(void* ctx, zx_device_t* parent)
+{
+    zx_status_t status;
+    unsigned i;
+
+    imx8_gpio_t* gpio = calloc(1, sizeof(imx8_gpio_t));
+    if (!gpio) {
+        return ZX_ERR_NO_MEMORY;
+    }
+
+    status = device_get_protocol(parent, ZX_PROTOCOL_PLATFORM_DEV, &gpio->pdev);
+    if (status != ZX_OK) {
+        zxlogf(ERROR, "%s: ZX_PROTOCOL_PLATFORM_DEV not available %d \n", __FUNCTION__, status);
+        goto fail;
+    }
+
+    status = device_get_protocol(parent, ZX_PROTOCOL_PLATFORM_BUS, &gpio->pbus);
+    if (status != ZX_OK) {
+        zxlogf(ERROR, "%s: ZX_PROTOCOL_PLATFORM_BUS not available %d\n", __FUNCTION__, status);
+        goto fail;
+    }
+
+    for (i = 0; i < countof(gpio->mmios); i++) {
+        status = pdev_map_mmio_buffer(&gpio->pdev, i, ZX_CACHE_POLICY_UNCACHED_DEVICE,
+                                        &gpio->mmios[i]);
+        if (status != ZX_OK) {
+            zxlogf(ERROR, "%s: pdev_map_mmio_buffer failed %d\n", __FUNCTION__, status);
+            goto fail;
+        }
+
+        mtx_init(&gpio->lock[i], mtx_plain);
+    }
+
+    device_add_args_t args = {
+        .version = DEVICE_ADD_ARGS_VERSION,
+        .name = "imx8-gpio",
+        .ctx = gpio,
+        .ops = &gpio_device_proto,
+        .flags = DEVICE_ADD_NON_BINDABLE,
+    };
+
+    status = device_add(parent, &args, &gpio->zxdev);
+    if (status != ZX_OK) {
+        zxlogf(ERROR, "%s: device_add failed! %d\n", __FUNCTION__, status);
+        goto fail;
+    }
+
+    gpio->gpio.ops = &gpio_ops;
+    gpio->gpio.ctx = gpio;
+    pbus_set_protocol(&gpio->pbus, ZX_PROTOCOL_GPIO, &gpio->gpio);
+
+    return ZX_OK;
+
+fail:
+    imx8_gpio_release(gpio);
+    return status;
+
+}
+
+static zx_driver_ops_t imx8_gpio_driver_ops = {
+    .version = DRIVER_OPS_VERSION,
+    .bind = imx8_gpio_bind,
+};
+
+ZIRCON_DRIVER_BEGIN(imx8_gpio, imx8_gpio_driver_ops, "zircon", "0.1", 6)
+    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PLATFORM_DEV),
+    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_NXP),
+    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_DID, PDEV_DID_IMX_GPIO),
+    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_PID, PDEV_PID_IMX8MEVK),
+ZIRCON_DRIVER_END(imx8_gpio)
diff --git a/system/dev/gpio/imx8/rules.mk b/system/dev/gpio/imx8/rules.mk
new file mode 100644
index 0000000..6ca7ced
--- /dev/null
+++ b/system/dev/gpio/imx8/rules.mk
@@ -0,0 +1,25 @@
+# Copyright 2018 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+MODULE_TYPE := driver
+
+MODULE_SRCS += \
+    $(LOCAL_DIR)/imx8-gpio.c \
+
+MODULE_STATIC_LIBS := \
+    system/ulib/ddk \
+    system/ulib/sync \
+
+MODULE_LIBS := \
+    system/ulib/driver \
+    system/ulib/c \
+    system/ulib/zircon \
+
+MODULE_HEADER_DEPS := system/dev/soc/imx8m
+
+include make/module.mk
diff --git a/system/dev/soc/imx8m/imx8m-iomux.c b/system/dev/soc/imx8m/imx8m-iomux.c
new file mode 100644
index 0000000..ca581b3
--- /dev/null
+++ b/system/dev/soc/imx8m/imx8m-iomux.c
@@ -0,0 +1,71 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdint.h>
+#include <threads.h>
+#include <unistd.h>
+#include <bits/limits.h>
+#include <ddk/debug.h>
+#include <hw/reg.h>
+
+#include <zircon/assert.h>
+#include <zircon/types.h>
+
+#include <soc/imx8m/imx8m.h>
+#include <soc/imx8m/imx8m-hw.h>
+#include <soc/imx8m/imx8m-iomux.h>
+
+zx_status_t imx8m_config_pin(imx8m_t *dev, iomux_cfg_struct* s_cfg, int size)
+{
+    int i;
+    volatile void* iomux = io_buffer_virt(&dev->iomuxc_base);
+
+    if (!dev || !(iomux) || !(s_cfg)) {
+        return ZX_ERR_INVALID_ARGS;
+    }
+
+    for (i = 0; i < size; i++) {
+        zxlogf(SPEW, "0x%lx\n", s_cfg[i]);
+        zxlogf(SPEW, "val = 0x%lx, reg = %p\n",
+                    IOMUX_CFG_MUX_MODE_VAL(GET_MUX_MODE_VAL(s_cfg[i])) |
+                    IOMUX_CFG_SION_VAL(GET_SION_VAL(s_cfg[i])),
+                    iomux + GET_MUX_CTL_OFF_VAL(s_cfg[i]));
+        zxlogf(SPEW, "val = 0x%lx, reg = %p\n",
+                    IOMUX_CFG_DSE_VAL(GET_DSE_VAL(s_cfg[i])) |
+                    IOMUX_CFG_SRE_VAL(GET_SRE_VAL(s_cfg[i])) |
+                    IOMUX_CFG_ODE_VAL(GET_ODE_VAL(s_cfg[i])) |
+                    IOMUX_CFG_PUE_VAL(GET_PUE_VAL(s_cfg[i])) |
+                    IOMUX_CFG_HYS_VAL(GET_HYS_VAL(s_cfg[i])) |
+                    IOMUX_CFG_LVTTL_VAL(GET_LVTTL_VAL(s_cfg[i])) |
+                    IOMUX_CFG_VSEL_VAL(GET_VSEL_VAL(s_cfg[i])),
+                    iomux + GET_PAD_CTL_OFF_VAL(s_cfg[i]));
+        zxlogf(SPEW, "val = 0x%lx, reg = %p\n",
+                    IOMUX_CFG_DAISY_VAL(GET_DAISY_VAL(s_cfg[i])),
+                    iomux + GET_SEL_INP_OFF_VAL(s_cfg[i]));
+
+        if (GET_MUX_CTL_OFF_VAL(s_cfg[i])) {
+            writel(
+                    IOMUX_CFG_MUX_MODE_VAL(GET_MUX_MODE_VAL(s_cfg[i])) |
+                    IOMUX_CFG_SION_VAL(GET_SION_VAL(s_cfg[i])),
+                        iomux + GET_MUX_CTL_OFF_VAL(s_cfg[i]));
+        }
+        if (GET_PAD_CTL_OFF_VAL(s_cfg[i])) {
+            writel(
+                    IOMUX_CFG_DSE_VAL(GET_DSE_VAL(s_cfg[i])) |
+                    IOMUX_CFG_SRE_VAL(GET_SRE_VAL(s_cfg[i])) |
+                    IOMUX_CFG_ODE_VAL(GET_ODE_VAL(s_cfg[i])) |
+                    IOMUX_CFG_PUE_VAL(GET_PUE_VAL(s_cfg[i])) |
+                    IOMUX_CFG_HYS_VAL(GET_HYS_VAL(s_cfg[i])) |
+                    IOMUX_CFG_LVTTL_VAL(GET_LVTTL_VAL(s_cfg[i])) |
+                    IOMUX_CFG_VSEL_VAL(GET_VSEL_VAL(s_cfg[i])),
+                        iomux + GET_PAD_CTL_OFF_VAL(s_cfg[i]));
+        }
+        if (GET_SEL_INP_OFF_VAL(s_cfg[i])) {
+            writel(IOMUX_CFG_DAISY_VAL(GET_DAISY_VAL(s_cfg[i])),
+                        iomux + GET_SEL_INP_OFF_VAL(s_cfg[i]));
+        }
+    }
+
+    return ZX_OK;
+}
\ No newline at end of file
diff --git a/system/dev/soc/imx8m/imx8m.c b/system/dev/soc/imx8m/imx8m.c
new file mode 100644
index 0000000..94fc390
--- /dev/null
+++ b/system/dev/soc/imx8m/imx8m.c
@@ -0,0 +1,57 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <threads.h>
+#include <unistd.h>
+
+#include <ddk/binding.h>
+#include <ddk/debug.h>
+#include <ddk/device.h>
+#include <ddk/driver.h>
+#include <ddk/protocol/platform-defs.h>
+
+#include <zircon/process.h>
+#include <zircon/syscalls.h>
+#include <zircon/assert.h>
+
+#include <soc/imx8m/imx8m.h>
+#include <soc/imx8m/imx8m-hw.h>
+#include <hw/reg.h>
+
+void imx8m_release(imx8m_t* imx8m)
+{
+    if (imx8m) {
+        io_buffer_release(&imx8m->iomuxc_base);
+    }
+    free(imx8m);
+}
+
+zx_status_t imx8m_init(zx_handle_t resource, zx_handle_t bti, imx8m_t** out)
+{
+    zx_status_t status;
+    imx8m_t* imx8m = calloc(1, sizeof(imx8m_t));
+    if (!imx8m) {
+        return ZX_ERR_NO_MEMORY;
+    }
+
+    if ( (status = io_buffer_init_physical(&imx8m->iomuxc_base, bti, IMX8M_AIPS_IOMUXC_BASE,
+                                            IMX8M_AIPS_LENGTH, resource,
+                                            ZX_CACHE_POLICY_UNCACHED_DEVICE)) != ZX_OK) {
+        goto fail;
+    }
+
+    *out = imx8m;
+    return ZX_OK;
+
+fail:
+    zxlogf(ERROR, "%s: failed %d\n", __FUNCTION__, status);
+    imx8m_release(imx8m);
+    return status;
+}
+
diff --git a/system/dev/soc/imx8m/include/soc/imx8m/imx8m-gpio.h b/system/dev/soc/imx8m/include/soc/imx8m/imx8m-gpio.h
new file mode 100644
index 0000000..6bad53d
--- /dev/null
+++ b/system/dev/soc/imx8m/include/soc/imx8m/imx8m-gpio.h
@@ -0,0 +1,24 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#pragma once
+
+#define IMX_GPIO_BLOCKS             5
+#define IMX_NUM_TO_BLOCK(x)         (x / 32)
+#define IMX_NUM_TO_BIT(x)           (x % 32)
+
+// IMX8M blocks are 1 based
+#define IMX_GPIO_PIN(block, num)  ((block-1) * 32 + num)
+
+#define GPIO_INPUT                      (0)
+#define GPIO_OUTPUT                     (1)
+
+#define IMX_GPIO_DR                     (0x0000)
+#define IMX_GPIO_GDIR                   (0x0004)
+#define IMX_GPIO_PSR                    (0x0008)
+#define IMX_GPIO_ICR1                   (0x000C)
+#define IMX_GPIO_ICR2                   (0x0010)
+#define IMX_GPIO_IMR                    (0x0014)
+#define IMX_GPIO_ISR                    (0x0018)
+#define IMX_GPIO_EDGE_SEL               (0x001C)
diff --git a/system/dev/soc/imx8m/include/soc/imx8m/imx8m-hw.h b/system/dev/soc/imx8m/include/soc/imx8m/imx8m-hw.h
new file mode 100644
index 0000000..8c1b7ea
--- /dev/null
+++ b/system/dev/soc/imx8m/include/soc/imx8m/imx8m-hw.h
@@ -0,0 +1,255 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#pragma once
+
+#define KB(x)                                               (x << 10)
+#define MB(x)                                               (x << 20)
+#define GB(x)                                               (x << 30)
+
+/* iMX8M Top Level A53 memory map */
+#define IMX8M_PCIE_1_BASE                                   0x18000000
+#define IMX8M_PCIE_1_LENGTH                                 MB(128)
+#define IMX8M_PCIE_2_BASE                                   0x20000000
+#define IMX8M_PCIE_2_LENGTH                                 MB(128)
+#define IMX8M_A53_DAP_BASE                                  0x28000000
+#define IMX8M_A53_DAP_LENGHT                                MB(16)
+#define IMX8M_GPU_BASE                                      0x38000000
+#define IMX8M_GPU_LENGTH                                    KB(64)
+#define IMX8M_USB1_BASE                                     0x38100000
+#define IMX8M_USB1_LENGTH                                   MB(1)
+#define IMX8M_USB2_BASE                                     0x38200000
+#define IMX8M_USB2_LENGTH                                   MB(1)
+#define IMX8M_VPU_BASE                                      0x38300000
+#define IMX8M_VPU_LENGTH                                    MB(2)
+#define IMX8M_GIC_BASE                                      0x38800000
+#define IMX8M_GIC_LENGTH                                    MB(1)
+
+/* iMX8M AIPS (Peripheral) Memory */
+#define IMX8M_AIPS_LENGTH                                   KB(64)
+#define IMX8M_AIPS_GPIO1_BASE                               0x30200000
+#define IMX8M_AIPS_GPIO2_BASE                               0x30210000
+#define IMX8M_AIPS_GPIO3_BASE                               0x30220000
+#define IMX8M_AIPS_GPIO4_BASE                               0x30230000
+#define IMX8M_AIPS_GPIO5_BASE                               0x30240000
+#define IMX8M_AIPS_WDOG1_BASE                               0x30280000
+#define IMX8M_AIPS_WDOG2_BASE                               0x30290000
+#define IMX8M_AIPS_WDOG3_BASE                               0x302A0000
+#define IMX8M_AIPS_GPT1_BASE                                0x302D0000
+#define IMX8M_AIPS_GPT2_BASE                                0x302E0000
+#define IMX8M_AIPS_GPT3_BASE                                0x302F0000
+#define IMX8M_AIPS_IOMUXC_BASE                              0x30330000
+#define IMX8M_AIPS_IOMUXC_GPR_BASE                          0x30340000
+#define IMX8M_AIPS_GPC_BASE                                 0x303A0000
+#define IMX8M_AIPS_PWM1_BASE                                0x30660000
+#define IMX8M_AIPS_PWM2_BASE                                0x30670000
+#define IMX8M_AIPS_PWM3_BASE                                0x30680000
+#define IMX8M_AIPS_PWM4_BASE                                0x30690000
+#define IMX8M_AIPS_GPT6_BASE                                0x306E0000
+#define IMX8M_AIPS_GPT5_BASE                                0x306F0000
+#define IMX8M_AIPS_GPT4_BASE                                0x30700000
+#define IMX8M_AIPS_SPDIF1_BASE                              0x30810000
+#define IMX8M_AIPS_ECSPI1_BASE                              0x30820000
+#define IMX8M_AIPS_ECSPI2_BASE                              0x30830000
+#define IMX8M_AIPS_ECSPI3_BASE                              0x30840000
+#define IMX8M_AIPS_UART1_BASE                               0x30860000
+#define IMX8M_AIPS_UART3_BASE                               0x30880000
+#define IMX8M_AIPS_UART2_BASE                               0x30890000
+#define IMX8M_AIPS_SPDIF2_BASE                              0x308A0000
+#define IMX8M_AIPS_MIPI_PHY_BASE                            0x30A00000
+#define IMX8M_AIPS_MIPI_DSI_BASE                            0x30A10000
+#define IMX8M_AIPS_I2C1_BASE                                0x30A20000
+#define IMX8M_AIPS_I2C2_BASE                                0x30A30000
+#define IMX8M_AIPS_I2C3_BASE                                0x30A40000
+#define IMX8M_AIPS_I2C4_BASE                                0x30A50000
+#define IMX8M_AIPS_UART4_BASE                               0x30A60000
+#define IMX8M_AIPS_USDHC1_BASE                              0x30B40000
+#define IMX8M_AIPS_USDHC2_BASE                              0x30B50000
+#define IMX8M_AIPS_QSPI_BASE                                0x30BB0000
+#define IMX8M_AIPS_ENET1_BASE                               0x30BE0000
+
+
+
+
+ #define IMX8M_A53_INTR_BOOT                                (32 + 0)
+ #define IMX8M_A53_INTR_DAP                                 (32 + 1)
+ #define IMX8M_A53_INTR_SDMA1                               (32 + 2)
+ #define IMX8M_A53_INTR_GPU                                 (32 + 3)
+ #define IMX8M_A53_INTR_SNVS_LP_WRAPPER                     (32 + 4)
+ #define IMX8M_A53_INTR_LCDIF                               (32 + 5)
+ #define IMX8M_A53_INTR_SPDIF1                              (32 + 6)
+ #define IMX8M_A53_INTR_H264DEC                             (32 + 7)
+ #define IMX8M_A53_INTR_VPUDMA                              (32 + 8)
+ #define IMX8M_A53_INTR_QOS                                 (32 + 9)
+ #define IMX8M_A53_INTR_WDOG3                               (32 + 10)
+ #define IMX8M_A53_INTR_HS                                  (32 + 11)
+ #define IMX8M_A53_INTR_APBHDMA                             (32 + 12)
+ #define IMX8M_A53_INTR_SPDIF2                              (32 + 13)
+ #define IMX8M_A53_INTR_SPDIF2                              (32 + 13)
+ #define IMX8M_A53_INTR_RAWNAND_BCH_COMP                    (32 + 14)
+ #define IMX8M_A53_INTR_RAWNAND_GPMI_TO                     (32 + 15)
+ #define IMX8M_A53_INTR_HDMI_IPS                            (32 + 16)
+ #define IMX8M_A53_INTR_HDMI_IPSx                           (32 + 17)
+ #define IMX8M_A53_INTR_HDMI_IPSy                           (32 + 18)
+ #define IMX8M_A53_INTR_SNVS_HP_WRAPPER_NOTZ                (32 + 19)
+ #define IMX8M_A53_INTR_SNVS_HP_WRAPPER_TZ                  (32 + 20)
+ #define IMX8M_A53_INTR_CSU                                 (32 + 21)
+ #define IMX8M_A53_INTR_USDHC1                              (32 + 22)
+ #define IMX8M_A53_INTR_USDHC2                              (32 + 23)
+ #define IMX8M_A53_INTR_DC8000_CONTROL                      (32 + 24)
+ #define IMX8M_A53_INTR_DTRC_WRAPPER                        (32 + 25)
+ #define IMX8M_A53_INTR_UART1                               (32 + 26)
+ #define IMX8M_A53_INTR_UART2                               (32 + 27)
+ #define IMX8M_A53_INTR_UART3                               (32 + 28)
+ #define IMX8M_A53_INTR_UART4                               (32 + 29)
+ #define IMX8M_A53_INTR_VP9DEC                              (32 + 30)
+ #define IMX8M_A53_INTR_ECSPI1                              (32 + 31)
+ #define IMX8M_A53_INTR_ECSPI2                              (32 + 32)
+ #define IMX8M_A53_INTR_ECSPI3                              (32 + 33)
+ #define IMX8M_A53_INTR_MIPI_DSI                            (32 + 34)
+ #define IMX8M_A53_INTR_I2C1                                (32 + 35)
+ #define IMX8M_A53_INTR_I2C2                                (32 + 36)
+ #define IMX8M_A53_INTR_I2C3                                (32 + 37)
+ #define IMX8M_A53_INTR_I2C4                                (32 + 38)
+ #define IMX8M_A53_INTR_RDC                                 (32 + 39)
+ #define IMX8M_A53_INTR_USB1                                (32 + 40)
+ #define IMX8M_A53_INTR_USB2                                (32 + 41)
+ #define IMX8M_A53_INTR_CSI1                                (32 + 42)
+ #define IMX8M_A53_INTR_CSI2                                (32 + 43)
+ #define IMX8M_A53_INTR_MIPI_CSI1                           (32 + 44)
+ #define IMX8M_A53_INTR_MIPI_CSI2                           (32 + 45)
+ #define IMX8M_A53_INTR_GPT6                                (32 + 46)
+ #define IMX8M_A53_INTR_SCTR0                               (32 + 47)
+ #define IMX8M_A53_INTR_SCTR1                               (32 + 48)
+ #define IMX8M_A53_INTR_ANAMIX_ALARM                        (32 + 49)
+ #define IMX8M_A53_INTR_ANAMIX_CRIT_ALARM                   (32 + 49)
+ #define IMX8M_A53_INTR_RESERVED                            (32 + 49)
+ #define IMX8M_A53_INTR_SAI3_RX                             (32 + 50)
+ #define IMX8M_A53_INTR_SAI3_RX_ASYNC                       (32 + 50)
+ #define IMX8M_A53_INTR_SAI3_TX                             (32 + 50)
+ #define IMX8M_A53_INTR_SAI3_TX_ASYNC                       (32 + 50)
+ #define IMX8M_A53_INTR_GPT5                                (32 + 51)
+ #define IMX8M_A53_INTR_GPT4                                (32 + 52)
+ #define IMX8M_A53_INTR_GPT3                                (32 + 53)
+ #define IMX8M_A53_INTR_GPT2                                (32 + 54)
+ #define IMX8M_A53_INTR_GPT1                                (32 + 55)
+ #define IMX8M_A53_INTR_GPIO1_INT7                          (32 + 56)
+ #define IMX8M_A53_INTR_GPIO1_INT6                          (32 + 57)
+ #define IMX8M_A53_INTR_GPIO1_INT5                          (32 + 58)
+ #define IMX8M_A53_INTR_GPIO1_INT4                          (32 + 59)
+ #define IMX8M_A53_INTR_GPIO1_INT3                          (32 + 60)
+ #define IMX8M_A53_INTR_GPIO1_INT2                          (32 + 61)
+ #define IMX8M_A53_INTR_GPIO1_INT1                          (32 + 62)
+ #define IMX8M_A53_INTR_GPIO1_INT0                          (32 + 63)
+ #define IMX8M_A53_INTR_GPIO1_INT_COMB_0_15                 (32 + 64)
+ #define IMX8M_A53_INTR_GPIO1_INT_COMP_16_31                (32 + 65)
+ #define IMX8M_A53_INTR_GPIO2_INT_COMB_0_15                 (32 + 66)
+ #define IMX8M_A53_INTR_GPIO2_INT_COMP_16_31                (32 + 67)
+ #define IMX8M_A53_INTR_GPIO3_INT_COMB_0_15                 (32 + 68)
+ #define IMX8M_A53_INTR_GPIO3_INT_COMP_16_31                (32 + 69)
+ #define IMX8M_A53_INTR_GPIO4_INT_COMB_0_15                 (32 + 70)
+ #define IMX8M_A53_INTR_GPIO4_INT_COMP_16_31                (32 + 71)
+ #define IMX8M_A53_INTR_GPIO5_INT_COMB_0_15                 (32 + 72)
+ #define IMX8M_A53_INTR_GPIO5_INT_COMP_16_31                (32 + 73)
+ #define IMX8M_A53_INTR_PCIE_CTRL2                          (32 + 74)
+ #define IMX8M_A53_INTR_PCIE_CTRL2x                         (32 + 75)
+ #define IMX8M_A53_INTR_PCIE_CTRL2y                         (32 + 76)
+ #define IMX8M_A53_INTR_PCIE_CTRL2z                         (32 + 77)
+ #define IMX8M_A53_INTR_WDOG1                               (32 + 78)
+ #define IMX8M_A53_INTR_WDOG2                               (32 + 79)
+ #define IMX8M_A53_INTR_PCIE_CTRL2zz                        (32 + 80)
+ #define IMX8M_A53_INTR_PWM1                                (32 + 81)
+ #define IMX8M_A53_INTR_PWM2                                (32 + 82)
+ #define IMX8M_A53_INTR_PWM3                                (32 + 83)
+ #define IMX8M_A53_INTR_PWM4                                (32 + 84)
+ #define IMX8M_A53_INTR_CCMSRCGPCMIX_CCM1                   (32 + 85)
+ #define IMX8M_A53_INTR_CCMSRCGPCMIX_CMM2                   (32 + 86)
+ #define IMX8M_A53_INTR_CCMSRCGPCMIX_GPC1                   (32 + 87)
+ #define IMX8M_A53_INTR_MU                                  (32 + 88)
+ #define IMX8M_A53_INTR_CCMSRCGPCMIX                        (32 + 89)
+ #define IMX8M_A53_INTR_SAI5_RX                             (32 + 90)
+ #define IMX8M_A53_INTR_SAI5_RX_ASYNC                       (32 + 90)
+ #define IMX8M_A53_INTR_SAI5_TX                             (32 + 90)
+ #define IMX8M_A53_INTR_SAI5_TX_ASYNC                       (32 + 90)
+ #define IMX8M_A53_INTR_SAI6_RX                             (32 + 90)
+ #define IMX8M_A53_INTR_SAI6_RX_ASYNC                       (32 + 90)
+ #define IMX8M_A53_INTR_SAI6_TX                             (32 + 90)
+ #define IMX8M_A53_INTR_SAI6_TX_ASYNC                       (32 + 90)
+ #define IMX8M_A53_INTR_RTIC                                (32 + 91)
+ #define IMX8M_A53_INTR_CPU_PMUIRQ_0                        (32 + 92)
+ #define IMX8M_A53_INTR_CPU_PMUIRQ_1                        (32 + 92)
+ #define IMX8M_A53_INTR_CPU_PMUIRQ_2                        (32 + 92)
+ #define IMX8M_A53_INTR_CPU_PMUIRQ_3                        (32 + 92)
+ #define IMX8M_A53_INTR_CPU_NCTIIRQ_0                       (32 + 93)
+ #define IMX8M_A53_INTR_CPU_NCTIIRQ_2                       (32 + 93)
+ #define IMX8M_A53_INTR_CPU_NCTIIRQ_3                       (32 + 93)
+ #define IMX8M_A53_INTR_CPU_NCTIIRQ_4                       (32 + 93)
+ #define IMX8M_A53_INTR_CCMSRCGPCMIX_WDOG                   (32 + 94)
+ #define IMX8M_A53_INTR_SAI1_RX                             (32 + 95)
+ #define IMX8M_A53_INTR_SAI1_RX_ASYNC                       (32 + 95)
+ #define IMX8M_A53_INTR_SAI1_TX                             (32 + 95)
+ #define IMX8M_A53_INTR_SAI1_TX_ASYNC                       (32 + 95)
+ #define IMX8M_A53_INTR_SAI2_RX                             (32 + 96)
+ #define IMX8M_A53_INTR_SAI2_RX_ASYNC                       (32 + 96)
+ #define IMX8M_A53_INTR_SAI2_TX                             (32 + 96)
+ #define IMX8M_A53_INTR_SAI2_TX_ASYNC                       (32 + 96)
+ #define IMX8M_A53_INTR_MU_M4                               (32 + 97)
+ #define IMX8M_A53_INTR_DDR                                 (32 + 98)
+ #define IMX8M_A53_INTR_SAI4_RX                             (32 + 100)
+ #define IMX8M_A53_INTR_SAI4_RX_ASYNC                       (32 + 100)
+ #define IMX8M_A53_INTR_SAI4_TX                             (32 + 100)
+ #define IMX8M_A53_INTR_SAI4_TX_ASYNC                       (32 + 100)
+ #define IMX8M_A53_INTR_CPU_ERR_AXI                         (32 + 101)
+ #define IMX8M_A53_INTR_CPU_L2_RAM_ECC                      (32 + 102)
+ #define IMX8M_A53_INTR_SDMA2                               (32 + 103)
+ #define IMX8M_A53_INTR_RESERVED4                           (32 + 104)
+ #define IMX8M_A53_INTR_CAAM_WRAPPER                        (32 + 105)
+ #define IMX8M_A53_INTR_CAAM_WRAPPERx                       (32 + 106)
+ #define IMX8M_A53_INTR_QSPI                                (32 + 107)
+ #define IMX8M_A53_INTR_TZASC                               (32 + 108)
+ #define IMX8M_A53_INTR_RESERVED1                           (32 + 109)
+ #define IMX8M_A53_INTR_RESERVED2                           (32 + 110)
+ #define IMX8M_A53_INTR_RESERVED3                           (32 + 111)
+ #define IMX8M_A53_INTR_PERFMON1                            (32 + 112)
+ #define IMX8M_A53_INTR_PERFMON2                            (32 + 113)
+ #define IMX8M_A53_INTR_CAAM_WRAPPER_JQ                     (32 + 114)
+ #define IMX8M_A53_INTR_CAAM_WRAPPER_RECOVER                (32 + 115)
+ #define IMX8M_A53_INTR_HS_IRQ                              (32 + 116)
+ #define IMX8M_A53_INTR_HEVCDEC                             (32 + 117)
+ #define IMX8M_A53_INTR_ENET1_MAC0_RX_BUFFER_DONE           (32 + 118)
+ #define IMX8M_A53_INTR_ENET1_MAC0_RX_FRAME_DONE            (32 + 118)
+ #define IMX8M_A53_INTR_ENET1_MAC0_TX_BUFFER_DONE           (32 + 118)
+ #define IMX8M_A53_INTR_ENET1_MAC0_TX_FRAME_DONE            (32 + 118)
+ #define IMX8M_A53_INTR_ENET1_MAC0_RX_BUFFER_DONEx          (32 + 119)
+ #define IMX8M_A53_INTR_ENET1_MAC0_RX_FRAME_DONEx           (32 + 119)
+ #define IMX8M_A53_INTR_ENET1_MAC0_TX_BUFFER_DONEx          (32 + 119)
+ #define IMX8M_A53_INTR_ENET1_MAC0_TX_FRAME_DONEx           (32 + 119)
+ #define IMX8M_A53_INTR_ENET1_MAC0_PERI_TIMER_OF            (32 + 120)
+ #define IMX8M_A53_INTR_ENET1_MAC0_TIME_STAMP_AVAIL         (32 + 120)
+ #define IMX8M_A53_INTR_ENET1_MAC0_PAYLOAD_RX_ERROR         (32 + 120)
+ #define IMX8M_A53_INTR_ENET1_MAC0_TX_FIFO_UNDERRUN         (32 + 120)
+ #define IMX8M_A53_INTR_ENET1_MAC0_COLL_RETRY_LIMIT         (32 + 120)
+ #define IMX8M_A53_INTR_ENET1_MAC0_LATE_COLLISION           (32 + 120)
+ #define IMX8M_A53_INTR_ENET1_MAC0_ETHERNET_BUS_ERROR       (32 + 120)
+ #define IMX8M_A53_INTR_ENET1_MAC0_MII_DATA_TRANSFER        (32 + 120)
+ #define IMX8M_A53_INTR_ENET1_MAC0_RX_BUFFER_DONEy          (32 + 120)
+ #define IMX8M_A53_INTR_ENET1_MAC0_RX_FRAME_DONEy           (32 + 120)
+ #define IMX8M_A53_INTR_ENET1_MAC0_TX_BUFFER_DONEy          (32 + 120)
+ #define IMX8M_A53_INTR_ENET1_MAC0_TX_FRAME_DONEy           (32 + 120)
+ #define IMX8M_A53_INTR_ENET1_MAC0_GRACEFUL_STOP_           (32 + 120)
+ #define IMX8M_A53_INTR_ENET1_MAC0_BABBLING_TX_ERR          (32 + 120)
+ #define IMX8M_A53_INTR_ENET1_MAC0_BABBLING_RX_ERR          (32 + 120)
+ #define IMX8M_A53_INTR_ENET1_MAC0_RX_FLUSH_FRAME0          (32 + 120)
+ #define IMX8M_A53_INTR_ENET1_MAC0_RX_FLUSH_FRAME1          (32 + 120)
+ #define IMX8M_A53_INTR_ENET1_MAC0_RX_FLUSH_FRAME2          (32 + 120)
+ #define IMX8M_A53_INTR_ENET1_MAC0_WAKEUP_REQUEST_SYNC      (32 + 120)
+ #define IMX8M_A53_INTR_ENET1_MAC0_BABBLING_RX_ERR          (32 + 120)
+ #define IMX8M_A53_INTR_ENET1_MAC0_WAKEUP_REQ_SYNC          (32 + 120)
+ #define IMX8M_A53_INTR_ENET1_1588_INTR                     (32 + 121)
+ #define IMX8M_A53_INTR_PCIE_CTRL1                          (32 + 122)
+ #define IMX8M_A53_INTR_PCIE_CTRL1x                         (32 + 123)
+ #define IMX8M_A53_INTR_PCIE_CTRL1y                         (32 + 124)
+ #define IMX8M_A53_INTR_PCIE_CTRL1z                         (32 + 125)
+ #define IMX8M_A53_INTR_RESERVED5                           (32 + 126)
+ #define IMX8M_A53_INTR_PCIE_CTRL1zz                        (32 + 127)
diff --git a/system/dev/soc/imx8m/include/soc/imx8m/imx8m-iomux.h b/system/dev/soc/imx8m/include/soc/imx8m/imx8m-iomux.h
new file mode 100644
index 0000000..77c7457
--- /dev/null
+++ b/system/dev/soc/imx8m/include/soc/imx8m/imx8m-iomux.h
@@ -0,0 +1,550 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#pragma once
+
+/*
+ * iomux_cfg_struct is a 64 bit field that contains all the values needed for pinmux.
+ * [2:0]        :   MUXMODE: Select Pin functionality
+ * [3]          :   SION: Software Input On Field
+ * [6:4]        :   DSE: Drive Strength
+ * [8:7]        :   SRE:Slew Rate Field
+ * [9]          :   ODE: Open Drain Enable Field
+ * [10]         :   PUE: Pull Up Enable Field
+ * [11]         :   HYS: Schmitt Trigger Enable Field
+ * [12]         :   LVTTL: Lvttl Enable Field
+ * [15:13]      :   VSEL: Voltage Select Field
+ * [16]         :   DAISY: Input Select Field
+ * [23:17]      :   RSVD: Future Use
+ * [35:24]      :   MUX_CTL_OFF: Start of MUX_CTL register from IOMUX Base Register
+ * [47:36]      :   PAT_CTL_OFF: Start of PAT_CTL register from IOMUX Base Register
+ * [60:48]      :   SEL_INP_OFF: Start of Input Select register from IOMUX Base Register
+ * [64:61]      :   RSVD: Future Use
+ */
+typedef uint64_t iomux_cfg_struct;
+
+/* iomux_cfg_struct bit field definition */
+#define MUX_MODE_START        0
+#define MUX_MODE_COUNT        3
+#define SET_MUX_MODE_VAL(x)   \
+                        ((x & ((1 << MUX_MODE_COUNT) - 1)) << MUX_MODE_START)
+#define GET_MUX_MODE_VAL(x)   \
+                        ((x >> MUX_MODE_START)  & ((1 << MUX_MODE_COUNT) - 1))
+
+#define SION_START            3
+#define SION_COUNT            1
+#define SET_SION_VAL(x)   \
+                        ((x & ((1 << SION_COUNT) - 1)) << SION_START)
+#define GET_SION_VAL(x)   \
+                        ((x >> SION_START)  & ((1 << SION_COUNT) - 1))
+
+/* PAD CTRL Bit Defs */
+#define DSE_START             4
+#define DSE_COUNT             3
+#define SET_DSE_VAL(x)    \
+                        ((x & ((1 << DSE_COUNT) - 1)) << DSE_START)
+#define GET_DSE_VAL(x)    \
+                        ((x >> DSE_START)  & ((1 << DSE_COUNT) - 1))
+
+#define SRE_START             7
+#define SRE_COUNT             2
+#define SET_SRE_VAL(x)    \
+                        ((x & ((1 << SRE_COUNT) - 1)) << SRE_START)
+#define GET_SRE_VAL(x)    \
+                        ((x >> SRE_START)  & ((1 << SRE_COUNT) - 1))
+
+#define ODE_START             9
+#define ODE_COUNT             1
+#define SET_ODE_VAL(x)    \
+                        ((x & ((1 << ODE_COUNT) - 1)) << ODE_START)
+#define GET_ODE_VAL(x)    \
+                        ((x >> ODE_START)  & ((1 << ODE_COUNT) - 1))
+
+#define PUE_START             10
+#define PUE_COUNT             1
+#define SET_PUE_VAL(x)    \
+                        ((x & ((1 << PUE_COUNT) - 1)) << PUE_START)
+#define GET_PUE_VAL(x)    \
+                        ((x >> PUE_START)  & ((1 << PUE_COUNT) - 1))
+
+#define HYS_START             11
+#define HYS_COUNT             1
+#define SET_HYS_VAL(x)    \
+                        ((x & ((1 << HYS_COUNT) - 1)) << HYS_START)
+#define GET_HYS_VAL(x)    \
+                        ((x >> HYS_START)  & ((1 << HYS_COUNT) - 1))
+
+#define LVTTL_START           12
+#define LVTTL_COUNT           1
+#define SET_LVTTL_VAL(x)  \
+                        ((x & ((1 << LVTTL_COUNT) - 1)) << LVTTL_START)
+#define GET_LVTTL_VAL(x)  \
+                        ((x >> LVTTL_START)  & ((1 << LVTTL_COUNT) - 1))
+
+#define VSEL_START            13
+#define VSEL_COUNT            3
+#define SET_VSEL_VAL(x)   \
+                        ((x & ((1 << VSEL_COUNT) - 1)) << VSEL_START)
+#define GET_VSEL_VAL(x)   \
+                        ((x >> VSEL_START)  & ((1 << VSEL_COUNT) - 1))
+
+#define DAISY_START           16
+#define DAISY_COUNT           1
+#define SET_DAISY_VAL(x)  \
+                        ((x & ((1 << DAISY_COUNT) - 1)) << DAISY_START)
+#define GET_DAISY_VAL(x)  \
+                        ((x >> DAISY_START)  & ((1 << DAISY_COUNT) - 1))
+
+#define MUX_CTL_OFF_START     24
+#define MUX_CTL_OFF_COUNT     12
+#define SET_MUX_CTL_OFF_VAL(x) \
+                ((x & ((1 << MUX_CTL_OFF_COUNT) - 1)) << MUX_CTL_OFF_START)
+#define GET_MUX_CTL_OFF_VAL(x) \
+                ((x >> MUX_CTL_OFF_START)  & ((1 << MUX_CTL_OFF_COUNT) - 1))
+
+#define PAD_CTL_OFF_START     36
+#define PAD_CTL_OFF_COUNT     12
+#define SET_PAD_CTL_OFF_VAL(x) \
+                ((x & ((1 << PAD_CTL_OFF_COUNT) - 1)) << PAD_CTL_OFF_START)
+#define GET_PAD_CTL_OFF_VAL(x) \
+                ((x >> PAD_CTL_OFF_START)  & ((1 << PAD_CTL_OFF_COUNT) - 1))
+
+#define SEL_INP_OFF_START     48
+#define SEL_INP_OFF_COUNT     12
+#define SET_SEL_INP_OFF_VAL(x) \
+                ((x & ((1 << SEL_INP_OFF_COUNT) - 1)) << SEL_INP_OFF_START)
+#define GET_SEL_INP_OFF_VAL(x) \
+                ((x >> SEL_INP_OFF_START)  & ((1 << SEL_INP_OFF_COUNT) - 1))
+
+/* end of iomux_cfg_struct bit field definition */
+
+#define MAKE_PIN_CFG(mux_mode, sion, dse, sre, ode, pue, hys, lvttl, vsel, \
+                        daisy, mux_ctl_off, pad_ctl_off, sel_inp_off) \
+            SET_MUX_MODE_VAL(mux_mode)          | \
+            SET_SION_VAL(sion)                  | \
+            SET_DSE_VAL(dse)                    | \
+            SET_SRE_VAL(sre)                    | \
+            SET_ODE_VAL(ode)                    | \
+            SET_PUE_VAL(pue)                    | \
+            SET_HYS_VAL(hys)                    | \
+            SET_LVTTL_VAL(lvttl)                | \
+            SET_VSEL_VAL(vsel)                  | \
+            SET_DAISY_VAL(daisy)                | \
+            SET_MUX_CTL_OFF_VAL(mux_ctl_off)    | \
+            SET_PAD_CTL_OFF_VAL(pad_ctl_off)    | \
+            SET_SEL_INP_OFF_VAL(sel_inp_off)
+
+#define MAKE_PIN_CFG_UART(mux_mode, mux_ctl_off, pad_ctl_off, sel_inp_off) \
+            MAKE_PIN_CFG(mux_mode, 0, DSR_45_OHM, SRE_MEDIUM, 0, 0, 0, 0, 0, 0, \
+                mux_ctl_off, pad_ctl_off, sel_inp_off)
+
+#define MAKE_PIN_CFG_DEFAULT(mux_mode, mux_ctl_off) \
+            MAKE_PIN_CFG(mux_mode, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+                mux_ctl_off, 0x000ULL, 0x000ULL)
+
+
+/* IMX8M IOMUX Register Offsets */
+#define SW_MUX_CTL_PAD_GPIO1_IO00               0x0028ULL
+#define SW_MUX_CTL_PAD_GPIO1_IO01               0x002CULL
+#define SW_MUX_CTL_PAD_GPIO1_IO02               0x0030ULL
+#define SW_MUX_CTL_PAD_GPIO1_IO03               0x0034ULL
+#define SW_MUX_CTL_PAD_GPIO1_IO04               0x0038ULL
+#define SW_MUX_CTL_PAD_GPIO1_IO05               0x003CULL
+#define SW_MUX_CTL_PAD_GPIO1_IO06               0x0040ULL
+#define SW_MUX_CTL_PAD_GPIO1_IO07               0x0044ULL
+#define SW_MUX_CTL_PAD_GPIO1_IO08               0x0048ULL
+#define SW_MUX_CTL_PAD_GPIO1_IO09               0x004CULL
+#define SW_MUX_CTL_PAD_GPIO1_IO10               0x0050ULL
+#define SW_MUX_CTL_PAD_GPIO1_IO11               0x0054ULL
+#define SW_MUX_CTL_PAD_GPIO1_IO12               0x0058ULL
+#define SW_MUX_CTL_PAD_GPIO1_IO13               0x005CULL
+#define SW_MUX_CTL_PAD_GPIO1_IO14               0x0060ULL
+#define SW_MUX_CTL_PAD_GPIO1_IO15               0x0064ULL
+#define SW_MUX_CTL_PAD_ENET_MDC                 0x0068ULL
+#define SW_MUX_CTL_PAD_ENET_MDIO                0x006CULL
+#define SW_MUX_CTL_PAD_ENET_TD3                 0x0070ULL
+#define SW_MUX_CTL_PAD_ENET_TD2                 0x0074ULL
+#define SW_MUX_CTL_PAD_ENET_TD1                 0x0078ULL
+#define SW_MUX_CTL_PAD_ENET_TD0                 0x007CULL
+#define SW_MUX_CTL_PAD_ENET_TX_CTL              0x0080ULL
+#define SW_MUX_CTL_PAD_ENET_TXC                 0x0084ULL
+#define SW_MUX_CTL_PAD_ENET_RX_CTL              0x0088ULL
+#define SW_MUX_CTL_PAD_ENET_RXC                 0x008CULL
+#define SW_MUX_CTL_PAD_ENET_RD0                 0x0090ULL
+#define SW_MUX_CTL_PAD_ENET_RD1                 0x0094ULL
+#define SW_MUX_CTL_PAD_ENET_RD2                 0x0098ULL
+#define SW_MUX_CTL_PAD_ENET_RD3                 0x009CULL
+#define SW_MUX_CTL_PAD_SD1_CLK                  0x00A0ULL
+#define SW_MUX_CTL_PAD_SD1_CMD                  0x00A4ULL
+#define SW_MUX_CTL_PAD_SD1_DATA0                0x00A8ULL
+#define SW_MUX_CTL_PAD_SD1_DATA1                0x00ACULL
+#define SW_MUX_CTL_PAD_SD1_DATA2                0x00B0ULL
+#define SW_MUX_CTL_PAD_SD1_DATA3                0x00B4ULL
+#define SW_MUX_CTL_PAD_SD1_DATA4                0x00B8ULL
+#define SW_MUX_CTL_PAD_SD1_DATA5                0x00BCULL
+#define SW_MUX_CTL_PAD_SD1_DATA6                0x00C0ULL
+#define SW_MUX_CTL_PAD_SD1_DATA7                0x00C4ULL
+#define SW_MUX_CTL_PAD_SD1_RESET_B              0x00C8ULL
+#define SW_MUX_CTL_PAD_SD1_STROBE               0x00CCULL
+#define SW_MUX_CTL_PAD_SD2_CD_B                 0x00D0ULL
+#define SW_MUX_CTL_PAD_SD2_CLK                  0x00D4ULL
+#define SW_MUX_CTL_PAD_SD2_CMD                  0x00D8ULL
+#define SW_MUX_CTL_PAD_SD2_DATA0                0x00DCULL
+#define SW_MUX_CTL_PAD_SD2_DATA1                0x00E0ULL
+#define SW_MUX_CTL_PAD_SD2_DATA2                0x00E4ULL
+#define SW_MUX_CTL_PAD_SD2_DATA3                0x00E8ULL
+#define SW_MUX_CTL_PAD_SD2_RESET_B              0x00ECULL
+#define SW_MUX_CTL_PAD_SD2_WP                   0x00F0ULL
+#define SW_MUX_CTL_PAD_NAND_ALE                 0x00F4ULL
+#define SW_MUX_CTL_PAD_NAND_CE0_B               0x00F8ULL
+#define SW_MUX_CTL_PAD_NAND_CE1_B               0x00FCULL
+#define SW_MUX_CTL_PAD_NAND_CE2_B               0x0100ULL
+#define SW_MUX_CTL_PAD_NAND_CE3_B               0x0104ULL
+#define SW_MUX_CTL_PAD_NAND_CLE                 0x0108ULL
+#define SW_MUX_CTL_PAD_NAND_DATA00              0x010CULL
+#define SW_MUX_CTL_PAD_NAND_DATA01              0x0110ULL
+#define SW_MUX_CTL_PAD_NAND_DATA02              0x0114ULL
+#define SW_MUX_CTL_PAD_NAND_DATA03              0x0118ULL
+#define SW_MUX_CTL_PAD_NAND_DATA04              0x011CULL
+#define SW_MUX_CTL_PAD_NAND_DATA05              0x0120ULL
+#define SW_MUX_CTL_PAD_NAND_DATA06              0x0124ULL
+#define SW_MUX_CTL_PAD_NAND_DATA07              0x0128ULL
+#define SW_MUX_CTL_PAD_NAND_DQS                 0x012CULL
+#define SW_MUX_CTL_PAD_NAND_RE_B                0x0130ULL
+#define SW_MUX_CTL_PAD_NAND_READY_B             0x0134ULL
+#define SW_MUX_CTL_PAD_NAND_WE_B                0x0138ULL
+#define SW_MUX_CTL_PAD_NAND_WP_B                0x013CULL
+#define SW_MUX_CTL_PAD_SAI5_RXFS                0x0140ULL
+#define SW_MUX_CTL_PAD_SAI5_RXC                 0x0144ULL
+#define SW_MUX_CTL_PAD_SAI5_RXD0                0x0148ULL
+#define SW_MUX_CTL_PAD_SAI5_RXD1                0x014CULL
+#define SW_MUX_CTL_PAD_SAI5_RXD2                0x0150ULL
+#define SW_MUX_CTL_PAD_SAI5_RXD3                0x0154ULL
+#define SW_MUX_CTL_PAD_SAI5_MCLK                0x0158ULL
+#define SW_MUX_CTL_PAD_SAI1_RXFS                0x015CULL
+#define SW_MUX_CTL_PAD_SAI1_RXC                 0x0160ULL
+#define SW_MUX_CTL_PAD_SAI1_RXD0                0x0164ULL
+#define SW_MUX_CTL_PAD_SAI1_RXD1                0x0168ULL
+#define SW_MUX_CTL_PAD_SAI1_RXD2                0x016CULL
+#define SW_MUX_CTL_PAD_SAI1_RXD3                0x0170ULL
+#define SW_MUX_CTL_PAD_SAI1_RXD4                0x0174ULL
+#define SW_MUX_CTL_PAD_SAI1_RXD5                0x0178ULL
+#define SW_MUX_CTL_PAD_SAI1_RXD6                0x017CULL
+#define SW_MUX_CTL_PAD_SAI1_RXD7                0x0180ULL
+#define SW_MUX_CTL_PAD_SAI1_TXFS                0x0184ULL
+#define SW_MUX_CTL_PAD_SAI1_TXC                 0x0188ULL
+#define SW_MUX_CTL_PAD_SAI1_TXD0                0x018CULL
+#define SW_MUX_CTL_PAD_SAI1_TXD1                0x0190ULL
+#define SW_MUX_CTL_PAD_SAI1_TXD2                0x0194ULL
+#define SW_MUX_CTL_PAD_SAI1_TXD3                0x0198ULL
+#define SW_MUX_CTL_PAD_SAI1_TXD4                0x019CULL
+#define SW_MUX_CTL_PAD_SAI1_TXD5                0x01A0ULL
+#define SW_MUX_CTL_PAD_SAI1_TXD6                0x01A4ULL
+#define SW_MUX_CTL_PAD_SAI1_TXD7                0x01A8ULL
+#define SW_MUX_CTL_PAD_SAI1_MCLK                0x01ACULL
+#define SW_MUX_CTL_PAD_SAI2_RXFS                0x01B0ULL
+#define SW_MUX_CTL_PAD_SAI2_RXC                 0x01B4ULL
+#define SW_MUX_CTL_PAD_SAI2_RXD0                0x01B8ULL
+#define SW_MUX_CTL_PAD_SAI2_TXFS                0x01BCULL
+#define SW_MUX_CTL_PAD_SAI2_TXC                 0x01C0ULL
+#define SW_MUX_CTL_PAD_SAI2_TXD0                0x01C4ULL
+#define SW_MUX_CTL_PAD_SAI2_MCLK                0x01C8ULL
+#define SW_MUX_CTL_PAD_SAI3_RXFS                0x01CCULL
+#define SW_MUX_CTL_PAD_SAI3_RXC                 0x01D0ULL
+#define SW_MUX_CTL_PAD_SAI3_RXD                 0x01D4ULL
+#define SW_MUX_CTL_PAD_SAI3_TXFS                0x01D8ULL
+#define SW_MUX_CTL_PAD_SAI3_TXC                 0x01DCULL
+#define SW_MUX_CTL_PAD_SAI3_TXD                 0x01E0ULL
+#define SW_MUX_CTL_PAD_SAI3_MCLK                0x01E4ULL
+#define SW_MUX_CTL_PAD_SPDIF_TX                 0x01E8ULL
+#define SW_MUX_CTL_PAD_SPDIF_RX                 0x01ECULL
+#define SW_MUX_CTL_PAD_SPDIF_EXT_CLK            0x01F0ULL
+#define SW_MUX_CTL_PAD_ECSPI1_SCLK              0x01F4ULL
+#define SW_MUX_CTL_PAD_ECSPI1_MOSI              0x01F8ULL
+#define SW_MUX_CTL_PAD_ECSPI1_MISO              0x01FCULL
+#define SW_MUX_CTL_PAD_ECSPI1_SS0               0x0200ULL
+#define SW_MUX_CTL_PAD_ECSPI2_SCLK              0x0204ULL
+#define SW_MUX_CTL_PAD_ECSPI2_MOSI              0x0208ULL
+#define SW_MUX_CTL_PAD_ECSPI2_MISO              0x020CULL
+#define SW_MUX_CTL_PAD_ECSPI2_SS0               0x0210ULL
+#define SW_MUX_CTL_PAD_I2C1_SCL                 0x0214ULL
+#define SW_MUX_CTL_PAD_I2C1_SDA                 0x0218ULL
+#define SW_MUX_CTL_PAD_I2C2_SCL                 0x021CULL
+#define SW_MUX_CTL_PAD_I2C2_SDA                 0x0220ULL
+#define SW_MUX_CTL_PAD_I2C3_SCL                 0x0224ULL
+#define SW_MUX_CTL_PAD_I2C3_SDA                 0x0228ULL
+#define SW_MUX_CTL_PAD_I2C4_SCL                 0x022CULL
+#define SW_MUX_CTL_PAD_I2C4_SDA                 0x0230ULL
+#define SW_MUX_CTL_PAD_UART1_RXD                0x0234ULL
+#define SW_MUX_CTL_PAD_UART1_TXD                0x0238ULL
+#define SW_MUX_CTL_PAD_UART2_RXD                0x023CULL
+#define SW_MUX_CTL_PAD_UART2_TXD                0x0240ULL
+#define SW_MUX_CTL_PAD_UART3_RXD                0x0244ULL
+#define SW_MUX_CTL_PAD_UART3_TXD                0x0248ULL
+#define SW_MUX_CTL_PAD_UART4_RXD                0x024CULL
+#define SW_MUX_CTL_PAD_UART4_TXD                0x0250ULL
+#define SW_PAD_CTL_PAD_TEST_MODE                0x0254ULL
+#define SW_PAD_CTL_PAD_BOOT_MODE0               0x0258ULL
+#define SW_PAD_CTL_PAD_BOOT_MODE1               0x025CULL
+#define SW_PAD_CTL_PAD_JTAG_MOD                 0x0260ULL
+#define SW_PAD_CTL_PAD_JTAG_TRST_B              0x0264ULL
+#define SW_PAD_CTL_PAD_JTAG_TDI                 0x0268ULL
+#define SW_PAD_CTL_PAD_JTAG_TMS                 0x026CULL
+#define SW_PAD_CTL_PAD_JTAG_TCK                 0x0270ULL
+#define SW_PAD_CTL_PAD_JTAG_TDO                 0x0274ULL
+#define SW_PAD_CTL_PAD_RTC                      0x0278ULL
+#define SW_PAD_CTL_PAD_PMIC_STBY_REQ            0x027CULL
+#define SW_PAD_CTL_PAD_PMIC_ON_REQ              0x0280ULL
+#define SW_PAD_CTL_PAD_ONOFF                    0x0284ULL
+#define SW_PAD_CTL_PAD_POR_B                    0x0288ULL
+#define SW_PAD_CTL_PAD_RTC_RESET_B              0x028CULL
+#define SW_PAD_CTL_PAD_GPIO1_IO00               0x0290ULL
+#define SW_PAD_CTL_PAD_GPIO1_IO01               0x0294ULL
+#define SW_PAD_CTL_PAD_GPIO1_IO02               0x0298ULL
+#define SW_PAD_CTL_PAD_GPIO1_IO03               0x029CULL
+#define SW_PAD_CTL_PAD_GPIO1_IO04               0x02A0ULL
+#define SW_PAD_CTL_PAD_GPIO1_IO05               0x02A4ULL
+#define SW_PAD_CTL_PAD_GPIO1_IO06               0x02A8ULL
+#define SW_PAD_CTL_PAD_GPIO1_IO07               0x02ACULL
+#define SW_PAD_CTL_PAD_GPIO1_IO08               0x02B0ULL
+#define SW_PAD_CTL_PAD_GPIO1_IO09               0x02B4ULL
+#define SW_PAD_CTL_PAD_GPIO1_IO10               0x02B8ULL
+#define SW_PAD_CTL_PAD_GPIO1_IO11               0x02BCULL
+#define SW_PAD_CTL_PAD_GPIO1_IO12               0x02C0ULL
+#define SW_PAD_CTL_PAD_GPIO1_IO13               0x02C4ULL
+#define SW_PAD_CTL_PAD_GPIO1_IO14               0x02C8ULL
+#define SW_PAD_CTL_PAD_GPIO1_IO15               0x02CCULL
+#define SW_PAD_CTL_PAD_ENET_MDC                 0x02D0ULL
+#define SW_PAD_CTL_PAD_ENET_MDIO                0x02D4ULL
+#define SW_PAD_CTL_PAD_ENET_TD3                 0x02D8ULL
+#define SW_PAD_CTL_PAD_ENET_TD2                 0x02DCULL
+#define SW_PAD_CTL_PAD_ENET_TD1                 0x02E0ULL
+#define SW_PAD_CTL_PAD_ENET_TD0                 0x02E4ULL
+#define SW_PAD_CTL_PAD_ENET_TX_CTL              0x02E8ULL
+#define SW_PAD_CTL_PAD_ENET_TXC                 0x02ECULL
+#define SW_PAD_CTL_PAD_ENET_RX_CTL              0x02F0ULL
+#define SW_PAD_CTL_PAD_ENET_RXC                 0x02F4ULL
+#define SW_PAD_CTL_PAD_ENET_RD0                 0x02F8ULL
+#define SW_PAD_CTL_PAD_ENET_RD1                 0x02FCULL
+#define SW_PAD_CTL_PAD_ENET_RD2                 0x0300ULL
+#define SW_PAD_CTL_PAD_ENET_RD3                 0x0304ULL
+#define SW_PAD_CTL_PAD_SD1_CLK                  0x0308ULL
+#define SW_PAD_CTL_PAD_SD1_CMD                  0x030CULL
+#define SW_PAD_CTL_PAD_SD1_DATA0                0x0310ULL
+#define SW_PAD_CTL_PAD_SD1_DATA1                0x0314ULL
+#define SW_PAD_CTL_PAD_SD1_DATA2                0x0318ULL
+#define SW_PAD_CTL_PAD_SD1_DATA3                0x031CULL
+#define SW_PAD_CTL_PAD_SD1_DATA4                0x0320ULL
+#define SW_PAD_CTL_PAD_SD1_DATA5                0x0324ULL
+#define SW_PAD_CTL_PAD_SD1_DATA6                0x0328ULL
+#define SW_PAD_CTL_PAD_SD1_DATA7                0x032CULL
+#define SW_PAD_CTL_PAD_SD1_RESET_B              0x0330ULL
+#define SW_PAD_CTL_PAD_SD1_STROBE               0x0334ULL
+#define SW_PAD_CTL_PAD_SD2_CD_B                 0x0338ULL
+#define SW_PAD_CTL_PAD_SD2_CLK                  0x033CULL
+#define SW_PAD_CTL_PAD_SD2_CMD                  0x0340ULL
+#define SW_PAD_CTL_PAD_SD2_DATA0                0x0344ULL
+#define SW_PAD_CTL_PAD_SD2_DATA1                0x0348ULL
+#define SW_PAD_CTL_PAD_SD2_DATA2                0x034CULL
+#define SW_PAD_CTL_PAD_SD2_DATA3                0x0350ULL
+#define SW_PAD_CTL_PAD_SD2_RESET_B              0x0354ULL
+#define SW_PAD_CTL_PAD_SD2_WP                   0x0358ULL
+#define SW_PAD_CTL_PAD_NAND_ALE                 0x035CULL
+#define SW_PAD_CTL_PAD_NAND_CE0_B               0x0360ULL
+#define SW_PAD_CTL_PAD_NAND_CE1_B               0x0364ULL
+#define SW_PAD_CTL_PAD_NAND_CE2_B               0x0368ULL
+#define SW_PAD_CTL_PAD_NAND_CE3_B               0x036CULL
+#define SW_PAD_CTL_PAD_NAND_CLE                 0x0370ULL
+#define SW_PAD_CTL_PAD_NAND_DATA00              0x0374ULL
+#define SW_PAD_CTL_PAD_NAND_DATA01              0x0378ULL
+#define SW_PAD_CTL_PAD_NAND_DATA02              0x037CULL
+#define SW_PAD_CTL_PAD_NAND_DATA03              0x0380ULL
+#define SW_PAD_CTL_PAD_NAND_DATA04              0x0384ULL
+#define SW_PAD_CTL_PAD_NAND_DATA05              0x0388ULL
+#define SW_PAD_CTL_PAD_NAND_DATA06              0x038CULL
+#define SW_PAD_CTL_PAD_NAND_DATA07              0x0390ULL
+#define SW_PAD_CTL_PAD_NAND_DQS                 0x0394ULL
+#define SW_PAD_CTL_PAD_NAND_RE_B                0x0398ULL
+#define SW_PAD_CTL_PAD_NAND_READY_B             0x039CULL
+#define SW_PAD_CTL_PAD_NAND_WE_B                0x03A0ULL
+#define SW_PAD_CTL_PAD_NAND_WP_B                0x03A4ULL
+#define SW_PAD_CTL_PAD_SAI5_RXFS                0x03A8ULL
+#define SW_PAD_CTL_PAD_SAI5_RXC                 0x03ACULL
+#define SW_PAD_CTL_PAD_SAI5_RXD0                0x03B0ULL
+#define SW_PAD_CTL_PAD_SAI5_RXD1                0x03B4ULL
+#define SW_PAD_CTL_PAD_SAI5_RXD2                0x03B8ULL
+#define SW_PAD_CTL_PAD_SAI5_RXD3                0x03BCULL
+#define SW_PAD_CTL_PAD_SAI5_MCLK                0x03C0ULL
+#define SW_PAD_CTL_PAD_SAI1_RXFS                0x03C4ULL
+#define SW_PAD_CTL_PAD_SAI1_RXC                 0x03C8ULL
+#define SW_PAD_CTL_PAD_SAI1_RXD0                0x03CCULL
+#define SW_PAD_CTL_PAD_SAI1_RXD1                0x03D0ULL
+#define SW_PAD_CTL_PAD_SAI1_RXD2                0x03D4ULL
+#define SW_PAD_CTL_PAD_SAI1_RXD3                0x03D8ULL
+#define SW_PAD_CTL_PAD_SAI1_RXD4                0x03DCULL
+#define SW_PAD_CTL_PAD_SAI1_RXD5                0x03E0ULL
+#define SW_PAD_CTL_PAD_SAI1_RXD6                0x03E4ULL
+#define SW_PAD_CTL_PAD_SAI1_RXD7                0x03E8ULL
+#define SW_PAD_CTL_PAD_SAI1_TXFS                0x03ECULL
+#define SW_PAD_CTL_PAD_SAI1_TXC                 0x03F0ULL
+#define SW_PAD_CTL_PAD_SAI1_TXD0                0x03F4ULL
+#define SW_PAD_CTL_PAD_SAI1_TXD1                0x03F8ULL
+#define SW_PAD_CTL_PAD_SAI1_TXD2                0x03FCULL
+#define SW_PAD_CTL_PAD_SAI1_TXD3                0x0400ULL
+#define SW_PAD_CTL_PAD_SAI1_TXD4                0x0404ULL
+#define SW_PAD_CTL_PAD_SAI1_TXD5                0x0408ULL
+#define SW_PAD_CTL_PAD_SAI1_TXD6                0x040CULL
+#define SW_PAD_CTL_PAD_SAI1_TXD7                0x0410ULL
+#define SW_PAD_CTL_PAD_SAI1_MCLK                0x0414ULL
+#define SW_PAD_CTL_PAD_SAI2_RXFS                0x0418ULL
+#define SW_PAD_CTL_PAD_SAI2_RXC                 0x041CULL
+#define SW_PAD_CTL_PAD_SAI2_RXD0                0x0420ULL
+#define SW_PAD_CTL_PAD_SAI2_TXFS                0x0424ULL
+#define SW_PAD_CTL_PAD_SAI2_TXC                 0x0428ULL
+#define SW_PAD_CTL_PAD_SAI2_TXD0                0x042CULL
+#define SW_PAD_CTL_PAD_SAI2_MCLK                0x0430ULL
+#define SW_PAD_CTL_PAD_SAI3_RXFS                0x0434ULL
+#define SW_PAD_CTL_PAD_SAI3_RXC                 0x0438ULL
+#define SW_PAD_CTL_PAD_SAI3_RXD                 0x043CULL
+#define SW_PAD_CTL_PAD_SAI3_TXFS                0x0440ULL
+#define SW_PAD_CTL_PAD_SAI3_TXC                 0x0444ULL
+#define SW_PAD_CTL_PAD_SAI3_TXD                 0x0448ULL
+#define SW_PAD_CTL_PAD_SAI3_MCLK                0x044CULL
+#define SW_PAD_CTL_PAD_SPDIF_TX                 0x0450ULL
+#define SW_PAD_CTL_PAD_SPDIF_RX                 0x0454ULL
+#define SW_PAD_CTL_PAD_SPDIF_EXT_CLK            0x0458ULL
+#define SW_PAD_CTL_PAD_ECSPI1_SCLK              0x045CULL
+#define SW_PAD_CTL_PAD_ECSPI1_MOSI              0x0460ULL
+#define SW_PAD_CTL_PAD_ECSPI1_MISO              0x0464ULL
+#define SW_PAD_CTL_PAD_ECSPI1_SS0               0x0468ULL
+#define SW_PAD_CTL_PAD_ECSPI2_SCLK              0x046CULL
+#define SW_PAD_CTL_PAD_ECSPI2_MOSI              0x0470ULL
+#define SW_PAD_CTL_PAD_ECSPI2_MISO              0x0474ULL
+#define SW_PAD_CTL_PAD_ECSPI2_SS0               0x0478ULL
+#define SW_PAD_CTL_PAD_I2C1_SCL                 0x047CULL
+#define SW_PAD_CTL_PAD_I2C1_SDA                 0x0480ULL
+#define SW_PAD_CTL_PAD_I2C2_SCL                 0x0484ULL
+#define SW_PAD_CTL_PAD_I2C2_SDA                 0x0488ULL
+#define SW_PAD_CTL_PAD_I2C3_SCL                 0x048CULL
+#define SW_PAD_CTL_PAD_I2C3_SDA                 0x0490ULL
+#define SW_PAD_CTL_PAD_I2C4_SCL                 0x0494ULL
+#define SW_PAD_CTL_PAD_I2C4_SDA                 0x0498ULL
+#define SW_PAD_CTL_PAD_UART1_RXD                0x049CULL
+#define SW_PAD_CTL_PAD_UART1_TXD                0x04A0ULL
+#define SW_PAD_CTL_PAD_UART2_RXD                0x04A4ULL
+#define SW_PAD_CTL_PAD_UART2_TXD                0x04A8ULL
+#define SW_PAD_CTL_PAD_UART3_RXD                0x04ACULL
+#define SW_PAD_CTL_PAD_UART3_TXD                0x04B0ULL
+#define SW_PAD_CTL_PAD_UART4_RXD                0x04B4ULL
+#define SW_PAD_CTL_PAD_UART4_TXD                0x04B8ULL
+#define CCM_PMIC_READY_SELECT_INPUT             0x04BCULL
+#define ENET1_MDIO_SELECT_INPUT                 0x04C0ULL
+#define SAI1_RX_SYNC_SELECT_INPUT               0x04C4ULL
+#define SAI1_TX_BCLK_SELECT_INPUT               0x04C8ULL
+#define SAI1_TX_SYNC_SELECT_INPUT               0x04CCULL
+#define SAI5_RX_BCLK_SELECT_INPUT               0x04D0ULL
+#define SAI5_RXD0_SELECT_INPUT                  0x04D4ULL
+#define SAI5_RXD1_SELECT_INPUT                  0x04D8ULL
+#define SAI5_RXD2_SELECT_INPUT                  0x04DCULL
+#define SAI5_RXD3_SELECT_INPUT                  0x04E0ULL
+#define SAI5_RX_SYNC_SELECT_INPUT               0x04E4ULL
+#define SAI5_TX_BCLK_SELECT_INPUT               0x04E8ULL
+#define SAI5_TX_SYNC_SELECT_INPUT               0x04ECULL
+#define UART1_RTS_B_SELECT_INPUT                0x04F0ULL
+#define UART1_RXD_SELECT_INPUT                  0x04F4ULL
+#define UART2_RTS_B_SELECT_INPUT                0x04F8ULL
+#define UART2_RXD_SELECT_INPUT                  0x04FCULL
+#define UART3_RTS_B_SELECT_INPUT                0x0500ULL
+#define UART3_RXD_SELECT_INPUT                  0x0504ULL
+#define UART4_RTS_B_SELECT_INPUT                0x0508ULL
+#define UART4_RXD_SELECT_INPUT                  0x050CULL
+#define SAI6_RX_BCLK_SELECT_INPUT               0x0510ULL
+#define SAI6_RXD0_SELECT_INPUT                  0x0514ULL
+#define SAI6_RX_SYNC_SELECT_INPUT               0x0518ULL
+#define SAI6_TX_BCLK_SELECT_INPUT               0x051CULL
+#define SAI6_TX_SYNC_SELECT_INPUT               0x0520ULL
+#define PCIE1_CLKREQ_B_SELECT_INPUT             0x0524ULL
+#define PCIE2_CLKREQ_B_SELECT_INPUT             0x0528ULL
+#define SAI5_MCLK_SELECT_INPUT                  0x052CULL
+#define SAI6_MCLK_SELECT_INPUT                  0x0530ULL
+
+/* MUX CTRL Register Bit Defs */
+#define IOMUX_CFG_MUX_MODE_START        0
+#define IOMUX_CFG_MUX_MODE_COUNT        3
+#define IOMUX_CFG_MUX_MODE_VAL(x)   \
+                        ((x & ((1 << IOMUX_CFG_MUX_MODE_COUNT) - 1)) << IOMUX_CFG_MUX_MODE_START)
+
+#define IOMUX_CFG_SION_START            4
+#define IOMUX_CFG_SION_COUNT            1
+#define IOMUX_CFG_SION_VAL(x)   \
+                        ((x & ((1 << IOMUX_CFG_SION_COUNT) - 1)) << IOMUX_CFG_SION_START)
+
+/* PAD CTRL Bit Defs */
+#define IOMUX_CFG_DSE_START             0
+#define IOMUX_CFG_DSE_COUNT             3
+#define IOMUX_CFG_DSE_VAL(x)    \
+                        ((x & ((1 << IOMUX_CFG_DSE_COUNT) - 1)) << IOMUX_CFG_DSE_START)
+
+#define IOMUX_CFG_SRE_START             3
+#define IOMUX_CFG_SRE_COUNT             2
+#define IOMUX_CFG_SRE_VAL(x)    \
+                        ((x & ((1 << IOMUX_CFG_SRE_COUNT) - 1)) << IOMUX_CFG_SRE_START)
+
+#define IOMUX_CFG_ODE_START             5
+#define IOMUX_CFG_ODE_COUNT             1
+#define IOMUX_CFG_ODE_VAL(x)    \
+                        ((x & ((1 << IOMUX_CFG_ODE_COUNT) - 1)) << IOMUX_CFG_ODE_START)
+
+#define IOMUX_CFG_PUE_START             6
+#define IOMUX_CFG_PUE_COUNT             1
+#define IOMUX_CFG_PUE_VAL(x)    \
+                        ((x & ((1 << IOMUX_CFG_PUE_COUNT) - 1)) << IOMUX_CFG_PUE_START)
+
+#define IOMUX_CFG_HYS_START             7
+#define IOMUX_CFG_HYS_COUNT             1
+#define IOMUX_CFG_HYS_VAL(x)    \
+                        ((x & ((1 << IOMUX_CFG_HYS_COUNT) - 1)) << IOMUX_CFG_HYS_START)
+
+#define IOMUX_CFG_LVTTL_START           8
+#define IOMUX_CFG_LVTTL_COUNT           1
+#define IOMUX_CFG_LVTTL_VAL(x)  \
+                        ((x & ((1 << IOMUX_CFG_LVTTL_COUNT) - 1)) << IOMUX_CFG_LVTTL_START)
+
+#define IOMUX_CFG_VSEL_START            11
+#define IOMUX_CFG_VSEL_COUNT            3
+#define IOMUX_CFG_VSEL_VAL(x)   \
+                        ((x & ((1 << IOMUX_CFG_VSEL_COUNT) - 1)) << IOMUX_CFG_VSEL_START)
+
+#define IOMUX_CFG_DAISY_START           0
+#define IOMUX_CFG_DAISY_COUNT           1
+#define IOMUX_CFG_DAISY_VAL(x)  \
+                        ((x & ((1 << IOMUX_CFG_DAISY_COUNT) - 1)) << IOMUX_CFG_DAISY_START)
+
+
+#define DSE_HIZ                 (0x00)
+#define DSR_255_OHM             (0x01)
+#define DSR_105_OHM             (0x02)
+#define DSR_75_OHM              (0x03)
+#define DSR_85_OHM              (0x04)
+#define DSR_65_OHM              (0x05)
+#define DSR_45_OHM              (0x06)
+#define DSR_40_OHM              (0x07)
+
+#define SRE_SLOW                (0x00)
+#define SRE_MEDIUM              (0x01)
+#define SRE_FAST                (0x02)
+#define SRE_MAX                 (0x03)
+
+#define VSEL_0_AUTO             (0x00)
+#define VSEL_1_AUTO             (0x01)
+#define VSEL_2_AUTO             (0x02)
+#define VSEL_3_AUTO             (0x03)
+#define VSEL_4_MAN_3V3          (0x04)
+#define VSEL_5_MAN_2P5          (0x05)
+#define VSEL_6_MAN_2p5          (0x06)
+#define VSEL_7_MAN_1P2_1P8      (0x07)
+
+
+
+zx_status_t imx8m_config_pin(imx8m_t *dev, iomux_cfg_struct* s_cfg, int size);
\ No newline at end of file
diff --git a/system/dev/soc/imx8m/include/soc/imx8m/imx8m.h b/system/dev/soc/imx8m/include/soc/imx8m/imx8m.h
new file mode 100644
index 0000000..7f29819
--- /dev/null
+++ b/system/dev/soc/imx8m/include/soc/imx8m/imx8m.h
@@ -0,0 +1,15 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#pragma once
+
+#include <ddk/io-buffer.h>
+#include <ddk/protocol/gpio.h>
+#include <zircon/listnode.h>
+
+typedef struct {
+    io_buffer_t iomuxc_base;
+} imx8m_t;
+
+zx_status_t imx8m_init(zx_handle_t resource, zx_handle_t bti, imx8m_t** out);
diff --git a/system/dev/soc/imx8m/rules.mk b/system/dev/soc/imx8m/rules.mk
new file mode 100644
index 0000000..3e40632
--- /dev/null
+++ b/system/dev/soc/imx8m/rules.mk
@@ -0,0 +1,24 @@
+# Copyright 2018 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+MODULE_TYPE := userlib
+
+MODULE_SRCS += \
+    $(LOCAL_DIR)/imx8m.c \
+    $(LOCAL_DIR)/imx8m-iomux.c \
+
+MODULE_STATIC_LIBS := \
+    system/ulib/ddk \
+    system/ulib/sync \
+
+MODULE_LIBS := \
+    system/ulib/driver \
+    system/ulib/c \
+    system/ulib/zircon \
+
+include make/module.mk
diff --git a/system/ulib/ddk/include/ddk/protocol/platform-defs.h b/system/ulib/ddk/include/ddk/protocol/platform-defs.h
index 2b25325..7a578cf 100644
--- a/system/ulib/ddk/include/ddk/protocol/platform-defs.h
+++ b/system/ulib/ddk/include/ddk/protocol/platform-defs.h
@@ -75,4 +75,10 @@
 #define PDEV_VID_INTEL              8
 #define PDEV_DID_INTEL_CPU_TRACE    1 // Intel CPU tracing driver
 
+// NXP
+#define PDEV_VID_NXP                9
+#define PDEV_PID_IMX8MEVK           1
+
+#define PDEV_DID_IMX_GPIO           1
+
 __END_CDECLS;