/*
 * Copyright (c) 2015 Amlogic, Inc. All rights reserved.
 *
 * This source code is subject to the terms and conditions defined in the
 * file 'LICENSE' which is part of this source code package.
 *
 * USB low level routines
 */
#include "usb_boot.h"
#include "usb_ch9.h"
#include "dwc_pcd.h"
#include "dwc_pcd_irq.h"
#include "../platform.h"

gadget_wrapper_t gadget_wrapper;

static const struct usb_gadget_ops dwc_pcd_ops = {
	.get_frame		= NULL,
	.wakeup			= NULL,
	.set_selfpowered	= NULL,
};

#define USETW2(w, h, l) ((w)[0] = (u_int8_t)(l), (w)[1] = (u_int8_t)(h))
#define UCONSTW(x)      { (x) & 0xff, ((x) >> 8) & 0xff }
#define UCONSTDW(x)     { (x) & 0xff, ((x) >> 8) & 0xff, \
                          ((x) >> 16) & 0xff, ((x) >> 24) & 0xff }

#define UGETW(w) ((w)[0] | ((w)[1] << 8))
#define USETW(w, v) ((w)[0] = (u_int8_t)(v), (w)[1] = (u_int8_t)((v) >> 8))
#define UGETDW(w) ((w)[0] | ((w)[1] << 8) | ((w)[2] << 16) | ((w)[3] << 24))
#define USETDW(w, v) ((w)[0] = (u_int8_t)(v), \
                     (w)[1] = (u_int8_t)((v) >> 8), \
                     (w)[2] = (u_int8_t)((v) >> 16), \
                     (w)[3] = (u_int8_t)((v) >> 24))

#define UE_XFERTYPE     0x03
#define UE_CONTROL     0x00
#define UE_ISOCHRONOUS 0x01
#define UE_BULK        0x02
#define UE_INTERRUPT   0x03
#define UE_GET_XFERTYPE(a)      ((a) & UE_XFERTYPE)
#define UE_ISO_TYPE     0x0c
#define UE_ISO_ASYNC   0x04
#define UE_ISO_ADAPT   0x08
#define UE_ISO_SYNC    0x0c
#define UE_GET_ISO_TYPE(a)      ((a) & UE_ISO_TYPE)

#define UE_GET_DIR(a)   ((a) & 0x80)
#define UE_SET_DIR(a, d)        ((a) | (((d)&1) << 7))
#define UE_DIR_IN       0x80
#define UE_DIR_OUT      0x00
#define UE_ADDR         0x0f
#define UE_GET_ADDR(a)  ((a) & UE_ADDR)

static void dwc_otg_enable_dwc_interrupts(void)
{
	gintmsk_data_t intr_mask = {0};
	gahbcfg_data_t ahbcfg = {0};

	/* Clear any pending OTG Interrupts */
	dwc_write_reg32(DWC_REG_GOTGINT, 0xFFFFFFFF);
	/* Clear any pending interrupts */
	dwc_write_reg32(DWC_REG_GINTSTS, 0xFFFFFFFF);

	intr_mask.b.rxstsqlvl = 1;
	intr_mask.b.usbreset = 1;
	intr_mask.b.enumdone = 1;
	intr_mask.b.inepintr = 1;
	intr_mask.b.outepintr = 1;
	intr_mask.b.sofintr = 1;
	intr_mask.b.usbsuspend = 1;
	dwc_write_reg32(DWC_REG_GINTMSK, intr_mask.d32);

	/* Enable interrupts */
	ahbcfg.d32 = dwc_read_reg32(DWC_REG_GAHBCFG);
	ahbcfg.b.glblintrmsk = 1;
	dwc_write_reg32(DWC_REG_GAHBCFG, ahbcfg.d32);
}


static void dwc_otg_core_reset(void)
{
    grstctl_t greset = {0};
    u32 count = 0;

    /*
	* Wait for AHB master IDLE state.
	*/
    do {
        udelay(10);
        greset.d32 = dwc_read_reg32(DWC_REG_GRSTCTL);
        if (++count > 100000) {
            ERR("HANG! AHB Idle GRSTCTL=%0x\n", greset.d32);
            return;
        }
    } while (0 == greset.b.ahbidle);

    /*
	* Core Soft Reset
	*/
    count = 0;
    greset.b.csftrst = 1;
    dwc_write_reg32(DWC_REG_GRSTCTL, greset.d32);
    do {
        greset.d32 = dwc_read_reg32(DWC_REG_GRSTCTL);
        if (++count > 1000000) {
            ERR("HANG! Soft Reset GRSTCTL=%0x\n", greset.d32);
            break;
        }
    } while (1 == greset.b.csftrst);

	/*
	* Wait for 3 PHY Clocks
	*/
    wait_ms(10);
}

int f_dwc_core_init()
{
	gahbcfg_data_t	ahbcfg = {0};
	gusbcfg_data_t  usbcfg = {0};
	grstctl_t resetctl = {0};
	fifosize_data_t nptxfifosize;
	int i;

    DBG("\ndwc_otg core init enter!\n");

    set_usb_phy_config(0);

    if (0x4F543000 != (dwc_read_reg32(DWC_REG_GSNPSID) & 0xFFFFF000)) {
        ERR("Bad value for SNPSID\n");
        return -1;
    }

	dwc_otg_core_reset();

    /*
	* Initialize the DWC_otg core.
	*/
	usbcfg.d32 = dwc_read_reg32(DWC_REG_GUSBCFG);
	usbcfg.b.force_dev_mode = 1;
#if (defined CONFIG_USB_DEVICE_V2)
	usbcfg.b.usbtrdtim = 9;
#else
	usbcfg.b.usbtrdtim = 5;
#endif
	dwc_write_reg32(DWC_REG_GUSBCFG, usbcfg.d32);

	ahbcfg.b.dmaenable = 0;
	dwc_write_reg32(DWC_REG_GAHBCFG, ahbcfg.d32);

    dwc_modify_reg32(DWC_REG_DCTL, 0, 2);
    dwc_modify_reg32(DWC_REG_DCTL, 2, 0);

	/*
	* Do device or host intialization based on mode during PCD and HCD
	* initialization
	*/
    if (dwc_read_reg32(DWC_REG_GINTSTS) & 0x1) {
		DBG("Host Mode\n");
		return -1;
    }

	DBG("Device Mode\n");
	/* Restart the Phy Clock */
	dwc_write_reg32(DWC_REG_PCGCCTL, 0);

	/* Configure data FIFO sizes */
	/* Rx FIFO */
	dwc_write_reg32(DWC_REG_GRXFSIZ, 256);

	/* Non-periodic Tx FIFO */
	nptxfifosize.b.depth = 512;
	nptxfifosize.b.startaddr = 256;
	dwc_write_reg32(DWC_REG_GNPTXFSIZ, nptxfifosize.d32);

	/* Flush the FIFOs */
	dwc_otg_flush_fifo(0x10);

	/* Flush the Learning Queue. */
	resetctl.b.intknqflsh = 1;
	dwc_write_reg32(DWC_REG_GRSTCTL, resetctl.d32);

	/* Clear all pending Device Interrupts */
	dwc_write_reg32(DWC_REG_DIEPMSK, 0);
	dwc_write_reg32(DWC_REG_DOEPMSK, 0);
	dwc_write_reg32(DWC_REG_DAINT, 0xFFFFFFFF);
	dwc_write_reg32(DWC_REG_DAINTMSK, 0);

	for (i = 0; i < NUM_EP; i++) {
		dwc_write_reg32(DWC_REG_IN_EP_REG(i), 0);
		dwc_write_reg32(DWC_REG_OUT_EP_REG(i), 0);

		/* Device IN/OUT Endpoint Transfer Size */
		dwc_write_reg32(DWC_REG_IN_EP_TSIZE(i), 0);
		dwc_write_reg32(DWC_REG_OUT_EP_TSIZE(i), 0);
	}

	dwc_otg_enable_dwc_interrupts();

    return 0;
}



int usb_pcd_irq_loop()
{
	return f_dwc_pcd_irq();
}

struct usb_gadget* usb_pcd_get_gadget()
{
	return &gadget_wrapper.gadget;
}

int pcd_queue(u32 ep_num, u32 is_in, struct usb_request *req)
{
	return f_dwc_otg_ep_req_start(&gadget_wrapper.pcd, ep_num, is_in, req);
}

int dwc_otg_bind_gadget_driver(struct usb_gadget_driver *driver)
{
	gadget_wrapper.driver = driver;

	return 0;
}

static inline void dwcpcd_usb_ep_set_maxpacket_limit(struct usb_ep *ep,
                                              unsigned maxpacket_limit)
{
	ep->maxpacket = maxpacket_limit;
}

static int ep_enable(struct usb_ep *usb_ep,
		     const struct usb_endpoint_descriptor *ep_desc)
{
	int num;
	int dir;
	dwc_ep_t *ep;
	const usb_endpoint_descriptor_t *desc;

	desc = (const usb_endpoint_descriptor_t *)ep_desc;

	if (!desc) {
		printf("ep_desc is NULL\n");
		return 0;
	}

	if (!usb_ep || !ep_desc || ep_desc->bDescriptorType != USB_DT_ENDPOINT) {
		printf("bad ep or descriptor\n");
		return -1;
	}
	if (usb_ep == &gadget_wrapper.ep0) {
		printf("bad ep(0)\n");
		return -1;
	}

	/* Check FIFO size? */
	if (!ep_desc->wMaxPacketSize) {
		printf("bad %s maxpacket\n", usb_ep->name);
		return -1;
	}

	if (!gadget_wrapper.driver ||
	    gadget_wrapper.gadget.speed == USB_SPEED_UNKNOWN) {
		printf("bogus device state\n");
		return -1;
	}

	num = UE_GET_ADDR(desc->bEndpointAddress);
	dir = UE_GET_DIR(desc->bEndpointAddress);

	if (dir == UE_DIR_IN) {
		ep = &gadget_wrapper.pcd.dwc_eps[num].dwc_ep;
		gadget_wrapper.pcd.dwc_eps[num].desc = desc;
		gadget_wrapper.pcd.dwc_eps[num].priv = (void *)usb_ep;
	} else {
		ep = &gadget_wrapper.pcd.dwc_eps[num+1].dwc_ep;
		gadget_wrapper.pcd.dwc_eps[num+1].desc = desc;
		gadget_wrapper.pcd.dwc_eps[num+1].priv = (void *)usb_ep;
	}
	dwc_otg_bulk_ep_activate(ep);

	usb_ep->maxpacket = le16_to_cpu(ep_desc->wMaxPacketSize);

	return 0;
}

static int ep_disable(struct usb_ep *usb_ep)
{
	int retval = 0;

	if (!usb_ep) {
		return -1;
	}

	return retval;
}

static struct usb_request *dwc_otg_pcd_alloc_request(struct usb_ep *ep,
						     gfp_t gfp_flags)
{
	struct usb_request *usb_req;

	if (0 == ep) {
		printf("Invalid EP!\n");
		return 0;
	}
	usb_req = kmalloc(sizeof(*usb_req), gfp_flags);
	if (0 == usb_req) {
		printf("request allocation failed!\n");
		return 0;
	}
	memset(usb_req, 0, sizeof(*usb_req));
	usb_req->dma = 0xffffffff;

	return usb_req;
}

static void dwc_otg_pcd_free_request(struct usb_ep *ep, struct usb_request *req)
{
	if (0 == ep || 0 == req) {
		printf(
			 "Invalid ep or req argument!\n");
		return;
	}

	kfree(req);
}

static dwc_otg_pcd_ep_t *get_ep_from_handle(pcd_struct_t *pcd, void *handle)
{
	int i;
	if (pcd->dwc_eps[0].priv == handle)
		return &pcd->dwc_eps[0];

	for (i = 1; i < 5; i++) {
		if (pcd->dwc_eps[i].priv == handle) {
			return &pcd->dwc_eps[i];
		}
	}

	return NULL;
}


static int ep_queue(struct usb_ep *usb_ep, struct usb_request *usb_req,
		    gfp_t gfp_flags)
{
	pcd_struct_t *pcd;
	struct dwc_otg_pcd_ep *ep = NULL;
	int retval = 0;

	if (!usb_req || !usb_req->complete || !usb_req->buf) {
		printf("bad params\n");
		return -1;
	}

	if (!usb_ep) {
		printf("bad ep\n");
		return -1;
	}

	pcd = &gadget_wrapper.pcd;
	if (!gadget_wrapper.driver ||
	    gadget_wrapper.gadget.speed == USB_SPEED_UNKNOWN) {
		printf("gadget.speed=%d\n",
			    gadget_wrapper.gadget.speed);
		printf("bogus device state\n");
		return -2;
	}

	usb_req->status = -EINPROGRESS;
	usb_req->actual = 0;

	ep = get_ep_from_handle(pcd, (void *)usb_ep);
		if (!ep || (!ep->desc && ep->dwc_ep.num != 0)) {
			printf("bad ep\n");
			return -1;
	}

	ep->req = usb_req;

	pcd_queue(ep->dwc_ep.num, ep->dwc_ep.is_in, usb_req);

	if (retval)
		return -3;

	return 0;
}

static int ep_dequeue(struct usb_ep *usb_ep, struct usb_request *usb_req)
{
	if (!usb_ep || !usb_req) {
		printf("bad argument\n");
		return -EINVAL;
	}
	if (!gadget_wrapper.driver ||
	    gadget_wrapper.gadget.speed == USB_SPEED_UNKNOWN) {
		printf("bogus device state\n");
		return -ESHUTDOWN;
	}

	return 0;
}

static int ep_halt(struct usb_ep *usb_ep, int value)
{
	depctl_data_t depctl;
	volatile u32 depctl_addr;
	pcd_struct_t *pcd;
	struct dwc_otg_pcd_ep *ep = NULL;

	if (value) {
		printf("can not halt ep\n");
		return -EINVAL;
	}

	pcd = &gadget_wrapper.pcd;
		if (!gadget_wrapper.driver ||
			gadget_wrapper.gadget.speed == USB_SPEED_UNKNOWN) {
			printf("gadget.speed=%d\n",
					gadget_wrapper.gadget.speed);
			printf("bogus device state\n");
			return -EINVAL;
	}

	if (!usb_ep) {
		printf("bad ep\n");
		return -EINVAL;
	}

	ep = get_ep_from_handle(pcd, (void *)usb_ep);
		if (!ep || (!ep->desc && ep->dwc_ep.num != 0)) {
			printf("bad ep\n");
			return -EINVAL;
	}

	if (ep->dwc_ep.is_in == 1)
		depctl_addr = DWC_REG_IN_EP_REG(1);
	else
		depctl_addr = DWC_REG_OUT_EP_REG(1);

	depctl.d32 = dwc_read_reg32(depctl_addr);

	/* clear the stall bits */
	depctl.b.stall = 0;

	/*
	 * USB Spec 9.4.5: For endpoints using data toggle, regardless
	 * of whether an endpoint has the Halt feature set, a
	 * ClearFeature(ENDPOINT_HALT) request always results in the
	 * data toggle being reinitialized to DATA0.
	 */
	depctl.b.setd0pid = 1;

	dwc_write_reg32(depctl_addr, depctl.d32);

	return 0;
}


static struct usb_ep_ops dwc_otg_pcd_ep_ops = {
	.enable = ep_enable,
	.disable = ep_disable,
	.alloc_request = dwc_otg_pcd_alloc_request,
	.free_request = dwc_otg_pcd_free_request,
	.queue = ep_queue,
	.dequeue = ep_dequeue,
	.set_halt = ep_halt,

	.fifo_status = 0,
	.fifo_flush = 0,

};

void gadget_add_eps(gadget_wrapper_t *d)
{
	static const char *names[] = {
		"ep0",
		"ep1in",
		"ep1out",
	};
	int i;
	struct usb_ep *ep;
	int8_t dev_endpoints = 1;

	INIT_LIST_HEAD(&d->gadget.ep_list);
	d->gadget.ep0 = &d->ep0;
	d->gadget.speed = USB_SPEED_HIGH;

	INIT_LIST_HEAD(&d->gadget.ep0->ep_list);

	/**
	 * Initialize the EP0 structure.
	 */
	ep = &d->ep0;

	/* Init the usb_ep structure. */
	ep->name = names[0];
	ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;

	/**
	 * @todo NGS: What should the max packet size be set to
	 * here?  Before EP type is set?
	 */
	ep->maxpacket = 1024;
	d->pcd.dwc_eps[0].priv = (void *)ep;

	list_add_tail(&ep->ep_list, &d->gadget.ep_list);

	for (i = 0; i < (dev_endpoints); i++) {
		ep = &d->in_ep[i];

		/* Init the usb_ep structure. */
		ep->name = names[i+1];
		ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;

		/**
		 * @todo NGS: What should the max packet size be set to
		 * here?  Before EP type is set?
		 */
		ep->maxpacket = 512;
		dwcpcd_usb_ep_set_maxpacket_limit(ep, 512);
		list_add_tail(&ep->ep_list, &d->gadget.ep_list);
	}

	for (i = 0; i < dev_endpoints; i++) {
		ep = &d->out_ep[i];

		/* Init the usb_ep structure. */
		ep->name = names[i+2];
		ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;

		/**
		 * @todo NGS: What should the max packet size be set to
		 * here?  Before EP type is set?
		 */
		ep->maxpacket = 512;
		dwcpcd_usb_ep_set_maxpacket_limit(ep, 512);

		list_add_tail(&ep->ep_list, &d->gadget.ep_list);
	}

	/* remove ep0 from the list.  There is a ep0 pointer. */
	list_del_init(&d->ep0.ep_list);

	d->ep0.maxpacket = 64;
	dwcpcd_usb_ep_set_maxpacket_limit(&d->ep0, 64);
}

static void dwc_otg_pcd_init_ep(pcd_struct_t *pcd, dwc_otg_pcd_ep_t *pcd_ep,
				uint32_t is_in, uint32_t ep_num)
{
	/* Init EP structure */
	pcd_ep->desc = 0;
	pcd_ep->stopped = 1;
	pcd_ep->queue_sof = 0;

	/* Init DWC ep structure */
	pcd_ep->dwc_ep.is_in = is_in;
	pcd_ep->dwc_ep.num = ep_num;
	pcd_ep->dwc_ep.active = 0;
	pcd_ep->dwc_ep.tx_fifo_num = 0;
	/* Control until ep is actvated */
	pcd_ep->dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL;
	pcd_ep->dwc_ep.maxpacket = 1024;
	pcd_ep->dwc_ep.dma_addr = 0;
	pcd_ep->dwc_ep.start_xfer_buff = 0;
	pcd_ep->dwc_ep.xfer_buff = 0;
	pcd_ep->dwc_ep.xfer_len = 0;
	pcd_ep->dwc_ep.xfer_count = 0;
	pcd_ep->dwc_ep.sent_zlp = 0;
	pcd_ep->dwc_ep.total_len = 0;
}


int f_usb_pcd_init()
{
	/**
	 *  Initialized the PCD portion of the driver.
	*/
	return f_dwc_core_init();
}

/*
  Register entry point for the peripheral controller driver.
*/
int usb_gadget_register_driver(struct usb_gadget_driver *driver)
{
	gadget_wrapper_t *dev = &gadget_wrapper;
	dwc_otg_pcd_ep_t *ep;
	int retval = 0;

	if (!driver
	    || (driver->speed != USB_SPEED_FULL
		&& driver->speed != USB_SPEED_HIGH)
	    || !driver->bind || !driver->disconnect || !driver->setup)
		return -EINVAL;
	if (!dev)
		return -ENODEV;
	if (dev->driver)
		return -EBUSY;

	/* first hook up the driver ... */
	dev->driver = driver;

	if (retval) { /* TODO */
		printf("target device_add failed, error %d\n", retval);
		return retval;
	}

	ep = &gadget_wrapper.pcd.dwc_eps[0];
	dwc_otg_pcd_init_ep(&gadget_wrapper.pcd, ep, 0, 0);

	ep = &gadget_wrapper.pcd.dwc_eps[1];
	dwc_otg_pcd_init_ep(&gadget_wrapper.pcd, ep, 1 /* IN */ , 1);

	ep = &gadget_wrapper.pcd.dwc_eps[2];
	dwc_otg_pcd_init_ep(&gadget_wrapper.pcd, ep, 0 /* OUT */ , 1);

	gadget_wrapper.pcd.dwc_eps[0].dwc_ep.maxpacket = 64;
	gadget_wrapper.pcd.dwc_eps[0].dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL;
	gadget_wrapper.gadget.ops = &dwc_pcd_ops;

	gadget_add_eps(&gadget_wrapper);

	retval = driver->bind(&dev->gadget);
	if (retval) {
		dev->driver = 0;
		return retval;
	}

	f_usb_pcd_init();

	return 0;
}

int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
	gadget_wrapper_t *dev = &gadget_wrapper;

	if (!dev)
		return -ENODEV;
	if (!driver || driver != dev->driver)
		return -EINVAL;

	driver->disconnect(&dev->gadget);

	driver->unbind(&dev->gadget);

	dev->driver = NULL;

	return 0;
}

#if (defined CONFIG_USB_DEVICE_V2)
unsigned int fb_sofintr;
unsigned fb_curTime_sof;

void dwc_otg_power_off_phy_fb(void)
{
	gintsts_data_t  gintr_status;
	gintsts_data_t  gintr_msk;
	u32 count = 1000;
	u32 sof = 0;

	while (count--) {
		gintr_msk.d32 = dwc_read_reg32(DWC_REG_GINTMSK);
		gintr_status.d32 = dwc_read_reg32(DWC_REG_GINTSTS);

		//if ((gintr_status.d32 & gintr_msk.d32)== 0)
			//continue;

		gintr_status.d32 = gintr_status.d32 & gintr_msk.d32;
		if (gintr_status.b.sofintr) {
			sof = 1;
			dwc_write_reg32(DWC_REG_GINTSTS, gintr_status.d32);
			break;
		}

		dwc_write_reg32(DWC_REG_GINTSTS, gintr_status.d32);
		udelay(1);
	}

	if (!sof) {
		ERR("sof timeout, reset usb phy tuning\n");
		set_usb_phy21_tuning_update_reset();
		mdelay(150);
	}

	return;
}
#endif//#if (defined CONFIG_USB_DEVICE_V2)

int usb_gadget_handle_interrupts(int index)
{
#if (defined CONFIG_USB_DEVICE_V2)
	unsigned Time_sof = get_timer(0);

	if (((Time_sof - fb_curTime_sof) > 0x200) && (fb_sofintr)) {
		fb_sofintr = 0;
		dwc_otg_power_off_phy_fb();
	}
#endif

	return usb_pcd_irq_loop();
}
