// 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/platform-defs.h>
#include <hw/reg.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"

static pbus_mmio_t imx8mevk_display_mmios[] = {
    {
        .base = IMX8M_AIPS_DC_MST1_BASE,
        .length = IMX8M_AIPS_LENGTH,
    },
};

static const pbus_bti_t imx8mevk_display_btis[] = {
    {
        .iommu_index = 0,
        .bti_id = BTI_DISPLAY,
    },
};

static const pbus_dev_t display_dev = {
    .name = "display",
    .vid = PDEV_VID_NXP,
    .pid = PDEV_PID_IMX8MEVK,
    .did = PDEV_DID_IMX_DISPLAY,
    .mmios = imx8mevk_display_mmios,
    .mmio_count = countof(imx8mevk_display_mmios),
    .btis = imx8mevk_display_btis,
    .bti_count = countof(imx8mevk_display_btis),
};

/* 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),

    // eMMC (USDHC1) Pinmux
    MAKE_PIN_CFG_USDHC_CLK(0, SW_MUX_CTL_PAD_SD1_CLK,
                           SW_PAD_CTL_PAD_SD1_CLK),
    MAKE_PIN_CFG_USDHC(0, SW_MUX_CTL_PAD_SD1_CMD,
                       SW_PAD_CTL_PAD_SD1_CMD),
    MAKE_PIN_CFG_USDHC(0, SW_MUX_CTL_PAD_SD1_DATA0,
                       SW_PAD_CTL_PAD_SD1_DATA0),
    MAKE_PIN_CFG_USDHC(0, SW_MUX_CTL_PAD_SD1_DATA1,
                       SW_PAD_CTL_PAD_SD1_DATA1),
    MAKE_PIN_CFG_USDHC(0, SW_MUX_CTL_PAD_SD1_DATA2,
                       SW_PAD_CTL_PAD_SD1_DATA2),
    MAKE_PIN_CFG_USDHC(0, SW_MUX_CTL_PAD_SD1_DATA3,
                       SW_PAD_CTL_PAD_SD1_DATA3),
    MAKE_PIN_CFG_USDHC(0, SW_MUX_CTL_PAD_SD1_DATA4,
                       SW_PAD_CTL_PAD_SD1_DATA4),
    MAKE_PIN_CFG_USDHC(0, SW_MUX_CTL_PAD_SD1_DATA5,
                       SW_PAD_CTL_PAD_SD1_DATA5),
    MAKE_PIN_CFG_USDHC(0, SW_MUX_CTL_PAD_SD1_DATA6,
                       SW_PAD_CTL_PAD_SD1_DATA6),
    MAKE_PIN_CFG_USDHC(0, SW_MUX_CTL_PAD_SD1_DATA7,
                       SW_PAD_CTL_PAD_SD1_DATA7),
    MAKE_PIN_CFG_USDHC_CLK(0, SW_MUX_CTL_PAD_SD1_STROBE,
                           SW_PAD_CTL_PAD_SD1_STROBE),

    MAKE_PIN_CFG_DEFAULT(5, SW_MUX_CTL_PAD_SD1_RESET_B),
};

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

    // start the gpio driver first so we can do our initial pinmux
    if ((status = imx8m_gpio_init(bus)) != ZX_OK) {
        zxlogf(ERROR, "%s: failed %d\n", __FUNCTION__, status);
        goto fail;
    }

    // Pinmux
    for (unsigned i = 0; i < sizeof(imx8mevk_pinmux) / sizeof(imx8mevk_pinmux[0]); i++) {
        gpio_impl_set_alt_function(&bus->gpio, 0, imx8mevk_pinmux[i]);
    }

    if ((status = imx_i2c_init(bus)) != ZX_OK) {
        zxlogf(ERROR, "%s: failed %d\n", __FUNCTION__, status);
        goto fail;
    }

    if ((status = imx_usb_init(bus)) != ZX_OK) {
        zxlogf(ERROR, "%s: failed %d\n", __FUNCTION__, status);
        goto fail;
    }

    if ((status = imx_gpu_init(bus)) != ZX_OK) {
        zxlogf(ERROR, "%s: imx_gpu_init failed %d\n", __FUNCTION__, status);
        goto fail;
    }

    if ((status = imx8m_sdhci_init(bus)) != ZX_OK) {
        zxlogf(ERROR, "%s: failed %d\n", __FUNCTION__, status);
        goto fail;
    }

    if ((status = pbus_device_add(&bus->pbus, &display_dev)) != ZX_OK) {
        zxlogf(ERROR, "%s could not add display_dev: %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;
    }

    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(imx8mevk_bus, imx8mevk_bus_driver_ops, "zircon", "0.1", 6)
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PLATFORM_BUS),
    BI_GOTO_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_NXP, 0),
    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_PID, PDEV_PID_IMX8MEVK),
    BI_LABEL(0),
    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_GOOGLE),
    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_PID, PDEV_PID_MADRONE),
ZIRCON_DRIVER_END(imx8mevk_bus)
