/*
 * 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.c"

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");

	f_set_usb_phy_config();

    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 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;
		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;
		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;
	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->unbind(&dev->gadget);

	dev->driver = NULL;

	return 0;
}

int usb_gadget_handle_interrupts(void)
{
	return usb_pcd_irq_loop();
}
