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;