/*
 * This file is part of the libpayload project.
 *
 * Copyright (C) 2015 Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <libpayload.h>
#include <arch/cache.h>
#include <assert.h>
#include <endian.h>
#include <queue.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <usb/usb.h>

#include <udc/udc.h>
#include <udc/chipidea.h>
#include "chipidea_priv.h"

#ifdef DEBUG
#define debug(x...) printf(x)
#else
#define debug(x...) do {} while (0)
#endif

#define min(a, b) (((a) < (b)) ? (a) : (b))

static struct qh *get_qh(struct chipidea_pdata *p, int endpoint, int in_dir)
{
	assert(in_dir <= 1);
	return &p->qhlist[2 * endpoint + in_dir];
}

static unsigned int ep_to_bits(int ep, int in_dir)
{
	return ep + (in_dir ? 16 : 0);
}

static void clear_setup_ep(struct chipidea_pdata *p, int endpoint)
{
	writel(1 << endpoint, &p->opreg->epsetupstat);
}

static void clear_ep(struct chipidea_pdata *p, int endpoint, int in_dir)
{
	writel(1 << ep_to_bits(endpoint, in_dir), &p->opreg->epcomplete);
}

static int chipidea_hw_init(struct usbdev_ctrl *this, void *_opreg,
	const device_descriptor_t *dd)
{
	struct chipidea_opreg *opreg = _opreg;
	struct chipidea_pdata *p = CI_PDATA(this);

	p->opreg = phys_to_virt(opreg);
	p->qhlist = dma_memalign(4096, sizeof(struct qh) * CI_QHELEMENTS);
	memcpy(&this->device_descriptor, dd, sizeof(*dd));

	if (p->qhlist == NULL)
		die("failed to allocate memory for usb device mode");

	memset(p->qhlist, 0, sizeof(struct qh) * CI_QHELEMENTS);

	SLIST_INIT(&this->configs);

	int i;
	for (i = 0; i < 16; i++) {
		SIMPLEQ_INIT(&p->job_queue[i][0]);
		SIMPLEQ_INIT(&p->job_queue[i][1]);
	}

	for (i = 0; i < CI_QHELEMENTS; i++) {
		p->qhlist[i].config = QH_MPS(512) | QH_NO_AUTO_ZLT | QH_IOS;
		p->qhlist[i].td.next = TD_TERMINATE;
	}
	/* EP0 in/out are hardwired for SETUP */
	p->qhlist[0].config = QH_MPS(64) | QH_NO_AUTO_ZLT | QH_IOS;
	p->qhlist[1].config = QH_MPS(64) | QH_NO_AUTO_ZLT | QH_IOS;

	do {
		debug("waiting for usb phy clk valid: %x\n",
			readl(&p->opreg->susp_ctrl));
		mdelay(1);
	} while ((readl(&p->opreg->susp_ctrl) & (1 << 7)) == 0);

	writel(USBCMD_8MICRO | USBCMD_RST, &p->opreg->usbcmd);
	mdelay(1);

	/* enable device mode */
	writel(2, &p->opreg->usbmode);

	dcache_clean_by_mva(p->qhlist, sizeof(struct qh) * CI_QHELEMENTS);

	writel(virt_to_phys(p->qhlist), &p->opreg->epbase);
	writel(0xffffffff, &p->opreg->epflush);

	/* enable EP0 */
	writel((1 << 23) | (1 << 22) | (1 << 7) | (1 << 6),
		&p->opreg->epctrl[0]);

	/* clear status register */
	writel(readl(&p->opreg->usbsts), &p->opreg->usbsts);

	debug("taking controller out of reset\n");
	writel(USBCMD_8MICRO | USBCMD_RUN, &p->opreg->usbcmd);

	this->stall(this, 0, 0, 0);
	this->stall(this, 0, 1, 0);

	return 1;
}

static void chipidea_halt_ep(struct usbdev_ctrl *this, int ep, int in_dir)
{
	struct chipidea_pdata *p = CI_PDATA(this);
	writel(1 << ep_to_bits(ep, in_dir), &p->opreg->epflush);
	while (readl(&p->opreg->epflush))
		;
	clrbits_le32(&p->opreg->epctrl[ep], 1 << (7 + (in_dir ? 16 : 0)));

	while (!SIMPLEQ_EMPTY(&p->job_queue[ep][in_dir])) {
		struct job *job = SIMPLEQ_FIRST(&p->job_queue[ep][in_dir]);
		if (job->autofree)
			free(job->data);

		SIMPLEQ_REMOVE_HEAD(&p->job_queue[ep][in_dir], queue);
	}
}

static void chipidea_start_ep(struct usbdev_ctrl *this,
	int ep, int in_dir, int ep_type, int mps)
{
	struct chipidea_pdata *p = CI_PDATA(this);
	struct qh *qh = get_qh(p, ep, in_dir);
	qh->config = (mps << 16) | QH_NO_AUTO_ZLT | QH_IOS;
	dcache_clean_by_mva(qh, sizeof(*qh));
	in_dir = in_dir ? 1 : 0;
	debug("enabling %d-%d (type %d)\n", ep, in_dir, ep_type);
	/* enable endpoint, reset data toggle */
	setbits_le32(&p->opreg->epctrl[ep],
		((1 << 7) | (1 << 6) | (ep_type << 2)) << (in_dir*16));
	p->ep_busy[ep][in_dir] = 0;
	this->ep_mps[ep][in_dir] = mps;
}

static void advance_endpoint(struct chipidea_pdata *p, int endpoint, int in_dir)
{
	if (p->ep_busy[endpoint][in_dir])
		return;
	if (SIMPLEQ_EMPTY(&p->job_queue[endpoint][in_dir]))
		return;

	struct job *job = SIMPLEQ_FIRST(&p->job_queue[endpoint][in_dir]);
	struct qh *qh = get_qh(p, endpoint, in_dir);

	uint32_t start = (uint32_t)(uintptr_t)job->data;
	uint32_t offset = (start & 0xfff);
	/* unlike with typical EHCI controllers,
	 * a full TD transfers either 0x5000 bytes if
	 * page aligned or 0x4000 bytes if not.
	 */
	int maxsize = 0x5000;
	if (offset > 0)
		maxsize = 0x4000;
	uint32_t td_count = (job->length + maxsize - 1) / maxsize;

	/* special case for zero length packets */
	if (td_count == 0)
		td_count = 1;

	if (job->zlp)
		td_count++;

	struct td *tds = dma_memalign(32, sizeof(struct td) * td_count);
	memset(tds, 0, sizeof(struct td) * td_count);

	int i;
	int remaining = job->length;
	for (i = 0; i < td_count; i++) {
		int datacount = min(maxsize, remaining);

		debug("td %d, %d bytes\n", i, datacount);
		tds[i].next = (uint32_t)virt_to_phys(&tds[i+1]);
		tds[i].info = TD_INFO_LEN(datacount) | TD_INFO_ACTIVE;
		tds[i].page0 = start;
		tds[i].page1 = (start & 0xfffff000) + 0x1000;
		tds[i].page2 = (start & 0xfffff000) + 0x2000;
		tds[i].page3 = (start & 0xfffff000) + 0x3000;
		tds[i].page4 = (start & 0xfffff000) + 0x4000;
		remaining -= datacount;
		start = start + datacount;
	}
	tds[td_count - 1].next = TD_TERMINATE;
	tds[td_count - 1].info |= TD_INFO_IOC;

	qh->td.next = (uint32_t)virt_to_phys(tds);
	qh->td.info = 0;

	job->tds = tds;
	job->td_count = td_count;

	dcache_clean_by_mva(tds, sizeof(struct td) * td_count);
	dcache_clean_by_mva(job->data, job->length);
	dcache_clean_by_mva(qh, sizeof(*qh));

	debug("priming EP %d-%d with %zx bytes starting at %x (%p)\n", endpoint,
		in_dir, job->length, tds[0].page0, job->data);
	writel(1 << ep_to_bits(endpoint, in_dir), &p->opreg->epprime);
	while (readl(&p->opreg->epprime))
		;
	p->ep_busy[endpoint][in_dir] = 1;
}

static void handle_endpoint(struct usbdev_ctrl *this, int endpoint, int in_dir)
{
	struct chipidea_pdata *p = CI_PDATA(this);
	struct job *job = SIMPLEQ_FIRST(&p->job_queue[endpoint][in_dir]);
	SIMPLEQ_REMOVE_HEAD(&p->job_queue[endpoint][in_dir], queue);

	if (in_dir)
		dcache_invalidate_by_mva(job->data, job->length);

	int length = job->length;

	int i = 0;
	do {
		int active;
		do {
			dcache_invalidate_by_mva(&job->tds[i],
				sizeof(struct td));
			active = job->tds[i].info & TD_INFO_ACTIVE;
			debug("%d-%d: info %08x, page0 %x, next %x\n",
				endpoint, in_dir, job->tds[i].info,
				job->tds[i].page0, job->tds[i].next);
		} while (active);
		/*
		 * The controller writes back the length field in info
		 * with the number of bytes it did _not_ process.
		 * Hence, take the originally scheduled length and
		 * subtract whatever lengths we still find - that gives
		 * us the data that the controller did transfer.
		 */
		int remaining = job->tds[i].info >> 16;
		length -= remaining;
	} while (job->tds[i++].next != TD_TERMINATE);
	debug("%d-%d: scheduled %zd, now %d bytes\n", endpoint, in_dir,
		job->length, length);

	if (this->current_config &&
	    this->current_config->interfaces[0].handle_packet)
		this->current_config->interfaces[0].handle_packet(this,
			endpoint, in_dir, job->data, length);

	free(job->tds);
	if (job->autofree)
		free(job->data);
	free(job);
	p->ep_busy[endpoint][in_dir] = 0;

	advance_endpoint(p, endpoint, in_dir);
}

static void start_setup(struct usbdev_ctrl *this, int ep)
{
	dev_req_t dr;
	struct chipidea_pdata *p = CI_PDATA(this);
	struct qh *qh = get_qh(p, ep, 0);

	dcache_invalidate_by_mva(qh, sizeof(*qh));
	memcpy(&dr, qh->setup_data, sizeof(qh->setup_data));
	clear_setup_ep(p, ep);

#ifdef DEBUG
	hexdump((unsigned long)&dr, sizeof(dr));
#endif

	udc_handle_setup(this, ep, &dr);
}


static void chipidea_enqueue_packet(struct usbdev_ctrl *this, int endpoint,
	int in_dir, void *data, int len, int zlp, int autofree)
{
	struct chipidea_pdata *p = CI_PDATA(this);
	struct job *job = malloc(sizeof(*job));

	job->data = data;
	job->length = len;
	job->zlp = zlp;
	job->autofree = autofree;

	debug("adding job of %d bytes to EP %d-%d\n", len, endpoint, in_dir);
	SIMPLEQ_INSERT_TAIL(&p->job_queue[endpoint][in_dir], job, queue);

	if ((endpoint == 0) || (this->initialized))
		advance_endpoint(p, endpoint, in_dir);
}

static int chipidea_poll(struct usbdev_ctrl *this)
{
	struct chipidea_pdata *p = CI_PDATA(this);
	uint32_t sts = readl(&p->opreg->usbsts);
	writel(sts, &p->opreg->usbsts); /* clear */

	/* new information if the bus is high speed or not */
	if (sts & USBSTS_PCI) {
		debug("USB speed negotiation: ");
		if ((readl(&p->opreg->devlc) & DEVLC_HOSTSPEED_MASK)
		   == DEVLC_HOSTSPEED(2)) {
			debug("high speed\n");
			// TODO: implement
		} else {
			debug("full speed\n");
			// TODO: implement
		}
	}

	/* reset requested. stop all activities */
	if (sts & USBSTS_URI) {
		int i;
		debug("USB reset requested\n");
		if (this->initialized) {
			writel(readl(&p->opreg->epstat), &p->opreg->epstat);
			writel(readl(&p->opreg->epsetupstat),
				&p->opreg->epsetupstat);
			writel(0xffffffff, &p->opreg->epflush);
			for (i = 1; i < 16; i++)
				writel(0, &p->opreg->epctrl[i]);
			this->initialized = 0;
		}
		writel((1 << 22) | (1 << 6), &p->opreg->epctrl[0]);
		p->qhlist[0].config = QH_MPS(64) | QH_NO_AUTO_ZLT | QH_IOS;
		p->qhlist[1].config = QH_MPS(64) | QH_NO_AUTO_ZLT | QH_IOS;
		dcache_clean_by_mva(p->qhlist, 2 * sizeof(struct qh));
	}

	if (sts & (USBSTS_UEI | USBSTS_UI)) {
		uint32_t bitmap;
		int ep;

		/* This slightly deviates from the recommendation in the
		 * data sheets, but the strict ordering is to simplify
		 * handling control transfers, which are initialized in
		 * the third step with a SETUP packet, then proceed in
		 * the next poll loop with in transfers (either data or
		 * status phase), then optionally out transfers (status
		 * phase).
		 */

		/* in transfers */
		bitmap = (readl(&p->opreg->epcomplete) >> 16) & 0xffff;
		ep = 0;
		while (bitmap) {
			if (bitmap & 1) {
				debug("incoming packet on EP %d (in)\n", ep);
				handle_endpoint(this, ep, 1);
				clear_ep(p, ep & 0xf, 1);
			}
			bitmap >>= 1;
			ep++;
		}

		/* out transfers */
		bitmap = readl(&p->opreg->epcomplete) & 0xffff;
		ep = 0;
		while (bitmap) {
			if (bitmap & 1) {
				debug("incoming packet on EP %d (out)\n", ep);
				handle_endpoint(this, ep, 0);
				clear_ep(p, ep, 0);
			}
			bitmap >>= 1;
			ep++;
		}

		/* setup transfers */
		bitmap = readl(&p->opreg->epsetupstat);
		ep = 0;
		while (bitmap) {
			if (bitmap & 1) {
				debug("incoming packet on EP %d (setup)\n", ep);
				start_setup(this, ep);
			}
			bitmap >>= 1;
			ep++;
		}
	}

	return 1;
}

static void chipidea_force_shutdown(struct usbdev_ctrl *this)
{
	struct chipidea_pdata *p = CI_PDATA(this);
	writel(0xffffffff, &p->opreg->epflush);
	writel(USBCMD_8MICRO | USBCMD_RST, &p->opreg->usbcmd);
	writel(0, &p->opreg->usbmode);
	writel(USBCMD_8MICRO, &p->opreg->usbcmd);
	free(p->qhlist);
	free(p);
	free(this);
}

static void chipidea_shutdown(struct usbdev_ctrl *this)
{
	struct chipidea_pdata *p = CI_PDATA(this);
	int i, j;
	int is_empty = 0;
	while (!is_empty) {
		is_empty = 1;
		this->poll(this);
		for (i = 0; i < 16; i++)
			for (j = 0; j < 2; j++)
				if (!SIMPLEQ_EMPTY(&p->job_queue[i][j]))
					is_empty = 0;
	}
	chipidea_force_shutdown(this);
}

static void chipidea_set_address(struct usbdev_ctrl *this, int address)
{
	struct chipidea_pdata *p = CI_PDATA(this);
	writel((address << 25) | (1 << 24), &p->opreg->usbadr);
}

static void chipidea_stall(struct usbdev_ctrl *this,
	uint8_t ep, int in_dir, int set)
{
	struct chipidea_pdata *p = CI_PDATA(this);
	assert(ep < 16);
	uint32_t *ctrl = &p->opreg->epctrl[ep];
	in_dir = in_dir ? 1 : 0;
	if (set) {
		if (in_dir)
			setbits_le32(ctrl, 1 << 16);
		else
			setbits_le32(ctrl, 1 << 0);
	} else {
		/* reset STALL bit, reset data toggle */
		if (in_dir) {
			setbits_le32(ctrl, 1 << 22);
			clrbits_le32(ctrl, 1 << 16);
		} else {
			setbits_le32(ctrl, 1 << 6);
			clrbits_le32(ctrl, 1 << 0);
		}
	}
	this->ep_halted[ep][in_dir] = set;
}

static void *chipidea_malloc(size_t size)
{
	return dma_malloc(size);
}

static void chipidea_free(void *ptr)
{
	free(ptr);
}

struct usbdev_ctrl *chipidea_init(device_descriptor_t *dd)
{
	struct usbdev_ctrl *ctrl = calloc(1, sizeof(*ctrl));
	if (ctrl == NULL)
		return NULL;
	ctrl->pdata = calloc(1, sizeof(struct chipidea_pdata));
	if (ctrl->pdata == NULL) {
		free(ctrl);
		return NULL;
	}

	ctrl->poll = chipidea_poll;
	ctrl->add_gadget = udc_add_gadget;
	ctrl->add_strings = udc_add_strings;
	ctrl->enqueue_packet = chipidea_enqueue_packet;
	ctrl->force_shutdown = chipidea_force_shutdown;
	ctrl->shutdown = chipidea_shutdown;
	ctrl->set_address = chipidea_set_address;
	ctrl->stall = chipidea_stall;
	ctrl->halt_ep = chipidea_halt_ep;
	ctrl->start_ep = chipidea_start_ep;
	ctrl->alloc_data = chipidea_malloc;
	ctrl->free_data = chipidea_free;
	ctrl->initialized = 0;

	int i;
	ctrl->ep_mps[0][0] = 64;
	ctrl->ep_mps[0][1] = 64;
	for (i = 1; i < 16; i++) {
		ctrl->ep_mps[i][0] = 512;
		ctrl->ep_mps[i][1] = 512;
	}

	if (!chipidea_hw_init(ctrl, (void *)0x7d000000, dd)) {
		free(ctrl->pdata);
		free(ctrl);
		return NULL;
	}
	return ctrl;
}
