// 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/metadata.h>
#include <ddk/protocol/platform-bus.h>
#include <ddk/protocol/platform-defs.h>
#include <ddk/protocol/usb-mode-switch.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 <soc/imx8m/imx8m-sip.h>
#include <limits.h>
#include <hw/reg.h>
#include <zircon/syscalls/smc.h>
#include "imx8mevk.h"

static const pbus_mmio_t usb1_mmios[] = {
    {
        .base = IMX8M_USB1_BASE,
        .length = IMX8M_USB1_LENGTH,
    },
};
static const pbus_irq_t usb1_irqs[] = {
    {
        .irq = IMX8M_A53_INTR_USB1,
        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
    },
};

static const pbus_bti_t usb1_btis[] = {
    {
        .iommu_index = 0,
        .bti_id = BTI_USB1,
    },
};

static usb_mode_t usb1_mode = USB_MODE_HOST;

static const pbus_metadata_t usb1_metadata[] = {
    {
        .type       = DEVICE_METADATA_USB_MODE,
        .data       = &usb1_mode,
        .len        = sizeof(usb1_mode),
    }
};

// USB1 is USB-C OTG port
static const pbus_dev_t usb1_dev = {
    .name = "dwc3-1",
    .vid = PDEV_VID_GENERIC,
    .pid = PDEV_PID_GENERIC,
    .did = PDEV_DID_USB_DWC3,
    .mmios = usb1_mmios,
    .mmio_count = countof(usb1_mmios),
    .irqs = usb1_irqs,
    .irq_count = countof(usb1_irqs),
    .btis = usb1_btis,
    .bti_count = countof(usb1_btis),
    .metadata = usb1_metadata,
    .metadata_count = countof(usb1_metadata),
};

static const pbus_mmio_t usb2_mmios[] = {
    {
        .base = IMX8M_USB2_BASE,
        .length = IMX8M_USB2_LENGTH,
    },
};
static const pbus_irq_t usb2_irqs[] = {
    {
        .irq = IMX8M_A53_INTR_USB2,
        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
    },
};

static const pbus_bti_t usb2_btis[] = {
    {
        .iommu_index = 0,
        .bti_id = BTI_USB2,
    },
};

static usb_mode_t usb2_mode = USB_MODE_HOST;

static const pbus_metadata_t usb2_metadata[] = {
    {
        .type       = DEVICE_METADATA_USB_MODE,
        .data       = &usb2_mode,
        .len        = sizeof(usb2_mode),
    }
};

// USB1 is USB-A port, host only
static const pbus_dev_t usb2_dev = {
    .name = "dwc3-2",
    .vid = PDEV_VID_GENERIC,
    .pid = PDEV_PID_GENERIC,
    .did = PDEV_DID_USB_DWC3,
    .mmios = usb2_mmios,
    .mmio_count = countof(usb2_mmios),
    .irqs = usb2_irqs,
    .irq_count = countof(usb2_irqs),
    .btis = usb2_btis,
    .bti_count = countof(usb2_btis),
    .metadata = usb2_metadata,
    .metadata_count = countof(usb2_metadata),
};

zx_status_t imx_usb_phy_init(zx_paddr_t usb_base, size_t usb_length, zx_handle_t bti) {
    uint32_t reg;
    io_buffer_t usb_buf;
    zx_status_t status = io_buffer_init_physical(&usb_buf, bti, usb_base, usb_length,
                                        get_root_resource(), ZX_CACHE_POLICY_UNCACHED_DEVICE);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s io_buffer_init_physical failed %d\n", __FUNCTION__, status);
        return status;
    }

    volatile void* regs = io_buffer_virt(&usb_buf);
    //TODO: More stuff might be needed if we were to boot from our own bootloader.
    reg = readl(regs + USB_PHY_CTRL1);
    reg &= ~(USB_PHY_CTRL1_VDATSRCENB0 | USB_PHY_CTRL1_VDATDETENB0 |
			USB_PHY_CTRL1_COMMONONN);
    reg |= USB_PHY_CTRL1_RESET | USB_PHY_CTRL1_ATERESET;
    writel(reg, regs + USB_PHY_CTRL1);

    reg = readl(regs + USB_PHY_CTRL0);
    reg |= USB_PHY_CTRL0_REF_SSP_EN;
    writel(reg, regs + USB_PHY_CTRL0);

    reg = readl(regs + USB_PHY_CTRL2);
    reg |= USB_PHY_CTRL2_TXENABLEN0;
    writel(reg, regs + USB_PHY_CTRL2);

    reg = readl(regs + USB_PHY_CTRL1);
    reg &= ~(USB_PHY_CTRL1_RESET | USB_PHY_CTRL1_ATERESET);
    writel(reg, regs + USB_PHY_CTRL1);

    io_buffer_release(&usb_buf);
    return ZX_OK;
}

zx_status_t imx_usb_init(imx8mevk_bus_t* bus) {
    zx_status_t status;
    zx_handle_t bti;

    // turn on usb via smc calls
    zx_smc_parameters_t otg1_en_params = {.func_id = IMX8M_SIP_GPC,
                                          .arg1 = IMX8M_SIP_CONFIG_GPC_PM_DOMAIN,
                                          .arg2 = IMX8M_PD_USB_OTG1,
                                          .arg3 = 1};
    zx_smc_result_t smc_result;
    status = zx_smc_call(get_root_resource(), &otg1_en_params, &smc_result);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s: SMC call to turn USB on failed %d\n", __FUNCTION__, status);
        return status;
    }

    zx_smc_parameters_t otg2_en_params = {.func_id = IMX8M_SIP_GPC,
                                          .arg1 = IMX8M_SIP_CONFIG_GPC_PM_DOMAIN,
                                          .arg2 = IMX8M_PD_USB_OTG2,
                                          .arg3 = 1};
    status = zx_smc_call(get_root_resource(), &otg2_en_params, &smc_result);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s: SMC call to turn USB on failed %d\n", __FUNCTION__, status);
        return status;
    }

    status = iommu_get_bti(&bus->iommu, 0, BTI_BOARD, &bti);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s: iommu_get_bti failed %d\n", __FUNCTION__, status);
        return status;
    }

    status = imx_usb_phy_init(IMX8M_USB1_BASE, IMX8M_USB1_LENGTH, bti);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s: imx_usb_phy_init failed %d\n", __FUNCTION__, status);
        zx_handle_close(bti);
        return status;
    }
    status = imx_usb_phy_init(IMX8M_USB2_BASE, IMX8M_USB2_LENGTH, bti);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s: imx_usb_phy_init failed %d\n", __FUNCTION__, status);
        zx_handle_close(bti);
        return status;
    }
    zx_handle_close(bti);

    if ((status = pbus_device_add(&bus->pbus, &usb1_dev)) != ZX_OK) {
        zxlogf(ERROR, "imx_usb_init could not add usb1_dev: %d\n", status);
        return status;
    }
    if ((status = pbus_device_add(&bus->pbus, &usb2_dev)) != ZX_OK) {
        zxlogf(ERROR, "imx_usb_init could not add usb2_dev: %d\n", status);
        return status;
    }

    return ZX_OK;
}

