/*
 * Copyright 2017, Data61
 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
 * ABN 41 687 119 230.
 *
 * This software may be distributed and modified according to the terms of
 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
 * See "LICENSE_BSD2.txt" for details.
 *
 * @TAG(DATA61_BSD)
 */
#include <platsupport/clock.h>
#include <platsupport/gpio.h>
#include <platsupport/plat/gpio.h>
#include <platsupport/mach/pmic.h>
#include <platsupport/plat/sysreg.h>
#include <usb/usb_host.h>
#include "../../ehci/ehci.h"
#include "../../services.h"
#include "../usb_otg.h"
#include <stdio.h>
#include <stddef.h>
#include <usb/drivers/usb3503_hub.h>


#define USB2_HOST_CTRL_PADDR     0x12130000
#define USB2_HOST_CTRL_SIZE      0x1000
#define USB2_HOST_EHCI_PADDR     0x12110000
#define USB2_HOST_EHCI_SIZE      0x1000
#define USB2_HOST_OHCI_PADDR     0x12120000
#define USB2_HOST_OHCI_SIZE      0x1000
#define USB2_DEV_LINK_PADDR      0x12140000
#define USB2_DEV_LINK_SIZE       0x1000

#define USB2_HOST_IRQ            103

#define USBPHY_CTRL0_OFFSET      0x000
#define USBPHY_CTRL1_OFFSET      0x010
#define USBPHY_CTRL2_OFFSET      0x020
#define USBPHY_EHCI_OFFSET       0x030

#define USBPHY_CTRL_RESETALL     BIT(31)
#define USBPHY_CTRL0_SRCSEL(x)   (((x) & 0x03) << 19)
#define USBPHY_CTRLX_SRCSEL(x)   (((x) & 0x03) << 23)
#define USBPHY_CTRL0_FREQ_SEL(x) (((x) & 0x07) << 16)
#define USBPHY_CTRLX_FREQ_SEL(x) (((x) & 0x7F) << 16)
#define USBPHY_CTRL_UTMI_RESET   BIT(2)
#define USBPHY_CTRL_LINK_RESET   BIT(1)
#define USBPHY_CTRL_PHY_RESET    BIT(0)
#define USBPHY_CTRL_RESET        ( USBPHY_CTRL_UTMI_RESET | \
                                   USBPHY_CTRL_LINK_RESET | \
                                   USBPHY_CTRL_PHY_RESET  | \
                                   USBPHY_CTRL_RESETALL   )

#define USBPHY_EHCI_ENABLE       (BIT(29) | BIT(28) | BIT(27) | BIT(26))

#define REG32(base, offset)      (volatile uint32_t*)((void*)(base) + (offset))
#define PHYREG32(base, o)        REG32(base, USBPHY_##o##_OFFSET)

#define NRESET_GPIO              XEINT12
#define HUBCONNECT_GPIO          XEINT6
#define NINT_GPIO                XEINT7

static volatile void *_phy_regs = NULL;

static sysreg_t _sysreg;

/* EHCI registers */
static void *_usb_regs = NULL;
static const int _usb_irqs[] = {
    [USB_HOST0] = USB2_HOST_IRQ
};

/* GPIO subsystem for bit-bangined I2C and HUB control */
static gpio_sys_t gpio_sys;

/* HUB and PMIC on I2C4 */
static struct i2c_bb i2c_bb;
static i2c_bus_t i2c_bus;

/* Eth power control */
static pmic_t pmic;
/* Hub control */
static usb3503_t usb3503_hub;

static int usb_init_phy(ps_io_ops_t *io_ops)
{
    /* Map phy regs */
    if (_phy_regs == NULL) {
        _phy_regs = GET_RESOURCE(io_ops, USB2_HOST_CTRL);
    }
    exynos5_sysreg_init(io_ops, &_sysreg);
    exynos5_sysreg_usbphy_enable(USBPHY_USB2, &_sysreg);

    /* Hold in reset */
    *PHYREG32(_phy_regs, CTRL0) |= USBPHY_CTRL_RESET;
    *PHYREG32(_phy_regs, CTRL1) |= USBPHY_CTRL_RESET;
    *PHYREG32(_phy_regs, CTRL2) |= USBPHY_CTRL_RESET;
    ps_udelay(10);

    /* Setup clocks and enable PHY */
    *PHYREG32(_phy_regs, CTRL0) = USBPHY_CTRL0_FREQ_SEL(0x05) | USBPHY_CTRL0_SRCSEL(2) | BIT(10);
    *PHYREG32(_phy_regs, CTRL1) = USBPHY_CTRLX_FREQ_SEL(0x24) | USBPHY_CTRLX_SRCSEL(2);
    *PHYREG32(_phy_regs, CTRL2) = USBPHY_CTRLX_FREQ_SEL(0x24) | USBPHY_CTRLX_SRCSEL(2);

    /* Enable the EHCI controller */
    *PHYREG32(_phy_regs, EHCI) |= USBPHY_EHCI_ENABLE;

    ps_udelay(40);

    return 0;
}



/*******************************************/

static void hub_pwren(int state)
{
    if (state) {
        usb3503_connect(&usb3503_hub);
    } else {
        usb3503_disconnect(&usb3503_hub);
    }
}

static void eth_pwren(int state)
{
    if (state) {
        pmic_ldo_cfg(&pmic, LDO_ETH, LDO_ON, 3300);
        ps_mdelay(40);
    } else {
        pmic_ldo_cfg(&pmic, LDO_ETH, LDO_OFF, 3300);
    }
}

static void board_pwren(int port, int state)
{
    switch (port) {
    case 1:
        /* USB2 */
        break;
    case 2:
        /* HSIC Ethernet */
        eth_pwren(state);
        break;
    case 3:
        /* USB hub */
        hub_pwren(state);
        break;
    default:
        ZF_LOGF("Invalid port for power change\n");
    }
}

static int usb_plat_gpio_init(ps_io_ops_t *io_ops)
{
    int err;
    err = gpio_sys_init(io_ops, &gpio_sys);
    if (err) {
        ZF_LOGF("GPIO error\n");
    }
    err = i2c_bb_init(&gpio_sys, GPIOID(GPA2, 1), GPIOID(GPA2, 0), &i2c_bb, &i2c_bus);
    if (err) {
        ZF_LOGF("I2C error\n");
    }

    /* USB hub */
    err = usb3503_init(&i2c_bus, &gpio_sys, NRESET_GPIO, HUBCONNECT_GPIO,
                       NINT_GPIO, &usb3503_hub);
    if (err) {
        ZF_LOGF("Hub3503 error\n");
    }

    /* PMIC for ethernet power change */
    err = pmic_init(&i2c_bus, PMIC_BUSADDR, &pmic);
    if (err) {
        ZF_LOGF("PMIC error\n");
    }

    /* Turn off the eth chip */
    eth_pwren(0);
    return err;
}

int usb_host_init(enum usb_host_id id, ps_io_ops_t *io_ops, ps_mutex_ops_t *sync,
                  usb_host_t *hdev)
{
    int err;
    if (id < 0 || id > USB_NHOSTS) {
        return -1;
    }

    if (!io_ops || !hdev) {
        ZF_LOGF("Invalid arguments\n");
    }

    hdev->id = id;
    hdev->dman = &io_ops->dma_manager;
    hdev->sync = sync;

    /* Check device mappings */
    if (_usb_regs == NULL) {
        _usb_regs = GET_RESOURCE(io_ops, USB2_HOST_EHCI);
    }
    if (_usb_regs == NULL) {
        return -1;
    }

    /* Initialise GPIOs */
    if (usb_plat_gpio_init(io_ops)) {
        return -1;
    }

    /* Initialise the phy */
    if (usb_init_phy(io_ops)) {
        ZF_LOGE("PHY transceiver error");
        return -1;
    }

    err = ehci_host_init(hdev, (uintptr_t)_usb_regs, &board_pwren);

    return err;
}

const int *usb_host_irqs(usb_host_t *host, int *nirqs)
{
    if (host->id < 0 || host->id > USB_NHOSTS) {
        return NULL;
    }

    if (nirqs) {
        *nirqs = 1;
    }

    host->irqs = &_usb_irqs[host->id];
    return host->irqs;
}

int usb_plat_otg_init(usb_otg_t odev, ps_io_ops_t *io_ops)
{
    return -1;
}


