// SPDX-License-Identifier: GPL-2.0+
/*
 * bdc_udc.c - BRCM BDC USB3.0 device controller gagdet ops
 *
 * Copyright (C) 2014 Broadcom Corporation
 *
 * Author: Ashwini Pahuja
 *
 * Based on drivers under drivers/usb/gadget/udc/
 */
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
#include <linux/list.h>
#include <linux/interrupt.h>
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include <linux/usb/otg.h>
#include <linux/pm.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <asm/unaligned.h>
#include <linux/platform_device.h>

#include "bdc.h"
#include "bdc_ep.h"
#include "bdc_cmd.h"
#include "bdc_dbg.h"

static const struct usb_gadget_ops bdc_gadget_ops;

static const char * const conn_speed_str[] =  {
	"Not connected",
	"Full Speed",
	"Low Speed",
	"High Speed",
	"Super Speed",
};

/* EP0 initial descripror */
static struct usb_endpoint_descriptor bdc_gadget_ep0_desc = {
	.bLength = USB_DT_ENDPOINT_SIZE,
	.bDescriptorType = USB_DT_ENDPOINT,
	.bmAttributes = USB_ENDPOINT_XFER_CONTROL,
	.bEndpointAddress = 0,
	.wMaxPacketSize	= cpu_to_le16(EP0_MAX_PKT_SIZE),
};

/* Advance the srr dqp maintained by SW */
static void srr_dqp_index_advc(struct bdc *bdc, u32 srr_num)
{
	struct srr *srr;

	srr = &bdc->srr;
	dev_dbg_ratelimited(bdc->dev, "srr->dqp_index:%d\n", srr->dqp_index);
	srr->dqp_index++;
	/* rollback to 0 if we are past the last */
	if (srr->dqp_index == NUM_SR_ENTRIES)
		srr->dqp_index = 0;
}

/* connect sr */
static void bdc_uspc_connected(struct bdc *bdc)
{
	u32 speed, temp;
	u32 usppms;
	int ret;

	temp = bdc_readl(bdc->regs, BDC_USPC);
	speed = BDC_PSP(temp);
	dev_dbg(bdc->dev, "%s speed=%x\n", __func__, speed);
	switch (speed) {
	case BDC_SPEED_SS:
		bdc_gadget_ep0_desc.wMaxPacketSize =
						cpu_to_le16(EP0_MAX_PKT_SIZE);
		bdc->gadget.ep0->maxpacket = EP0_MAX_PKT_SIZE;
		bdc->gadget.speed = USB_SPEED_SUPER;
		/* Enable U1T in SS mode */
		usppms =  bdc_readl(bdc->regs, BDC_USPPMS);
		usppms &= ~BDC_U1T(0xff);
		usppms |= BDC_U1T(U1_TIMEOUT);
		usppms |= BDC_PORT_W1S;
		bdc_writel(bdc->regs, BDC_USPPMS, usppms);
		break;

	case BDC_SPEED_HS:
		bdc_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64);
		bdc->gadget.ep0->maxpacket = 64;
		bdc->gadget.speed = USB_SPEED_HIGH;
		break;

	case BDC_SPEED_FS:
		bdc_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64);
		bdc->gadget.ep0->maxpacket = 64;
		bdc->gadget.speed = USB_SPEED_FULL;
		break;

	case BDC_SPEED_LS:
		bdc_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(8);
		bdc->gadget.ep0->maxpacket = 8;
		bdc->gadget.speed = USB_SPEED_LOW;
		break;
	default:
		dev_err(bdc->dev, "UNDEFINED SPEED\n");
		return;
	}
	dev_dbg(bdc->dev, "connected at %s\n", conn_speed_str[speed]);
	/* Now we know the speed, configure ep0 */
	bdc->bdc_ep_array[1]->desc = &bdc_gadget_ep0_desc;
	ret = bdc_config_ep(bdc, bdc->bdc_ep_array[1]);
	if (ret)
		dev_err(bdc->dev, "EP0 config failed\n");
	bdc->bdc_ep_array[1]->usb_ep.desc = &bdc_gadget_ep0_desc;
	bdc->bdc_ep_array[1]->flags |= BDC_EP_ENABLED;
	usb_gadget_set_state(&bdc->gadget, USB_STATE_DEFAULT);
}

/* device got disconnected */
static void bdc_uspc_disconnected(struct bdc *bdc, bool reinit)
{
	struct bdc_ep *ep;

	dev_dbg(bdc->dev, "%s\n", __func__);
	/*
	 * Only stop ep0 from here, rest of the endpoints will be disabled
	 * from gadget_disconnect
	 */
	ep = bdc->bdc_ep_array[1];
	if (ep && (ep->flags & BDC_EP_ENABLED))
		/* if enabled then stop and remove requests */
		bdc_ep_disable(ep);

	if (bdc->gadget_driver && bdc->gadget_driver->disconnect) {
		spin_unlock(&bdc->lock);
		bdc->gadget_driver->disconnect(&bdc->gadget);
		spin_lock(&bdc->lock);
	}
	/* Set Unknown speed */
	bdc->gadget.speed = USB_SPEED_UNKNOWN;
	bdc->devstatus &= DEVSTATUS_CLEAR;
	bdc->delayed_status = false;
	bdc->reinit = reinit;
	bdc->test_mode = false;
}

/* TNotify wkaeup timer */
static void bdc_func_wake_timer(struct work_struct *work)
{
	struct bdc *bdc = container_of(work, struct bdc, func_wake_notify.work);
	unsigned long flags;

	dev_dbg(bdc->dev, "%s\n", __func__);
	spin_lock_irqsave(&bdc->lock, flags);
	/*
	 * Check if host has started transferring on endpoints
	 * FUNC_WAKE_ISSUED is cleared when transfer has started after resume
	*/
	if (bdc->devstatus & FUNC_WAKE_ISSUED) {
		dev_dbg(bdc->dev, "FUNC_WAKE_ISSUED FLAG IS STILL SET\n");
		/* flag is still set, so again send func wake */
		bdc_function_wake_fh(bdc, 0);
		schedule_delayed_work(&bdc->func_wake_notify,
						msecs_to_jiffies(BDC_TNOTIFY));
	}
	spin_unlock_irqrestore(&bdc->lock, flags);
}

/* handler for Link state change condition */
static void handle_link_state_change(struct bdc *bdc, u32 uspc)
{
	u32 link_state;

	dev_dbg(bdc->dev, "Link state change");
	link_state = BDC_PST(uspc);
	switch (link_state) {
	case BDC_LINK_STATE_U3:
		if ((bdc->gadget.speed != USB_SPEED_UNKNOWN) &&
						bdc->gadget_driver->suspend) {
			dev_dbg(bdc->dev, "Entered Suspend mode\n");
			spin_unlock(&bdc->lock);
			bdc->devstatus |= DEVICE_SUSPENDED;
			bdc->gadget_driver->suspend(&bdc->gadget);
			spin_lock(&bdc->lock);
		}
		break;
	case BDC_LINK_STATE_U0:
		if (bdc->devstatus & REMOTE_WAKEUP_ISSUED) {
					bdc->devstatus &= ~REMOTE_WAKEUP_ISSUED;
			if (bdc->gadget.speed == USB_SPEED_SUPER) {
				bdc_function_wake_fh(bdc, 0);
				bdc->devstatus |= FUNC_WAKE_ISSUED;
				/*
				 * Start a Notification timer and check if the
				 * Host transferred anything on any of the EPs,
				 * if not then send function wake again every
				 * TNotification secs until host initiates
				 * transfer to BDC, USB3 spec Table 8.13
				*/
				schedule_delayed_work(
						&bdc->func_wake_notify,
						msecs_to_jiffies(BDC_TNOTIFY));
				dev_dbg(bdc->dev, "sched func_wake_notify\n");
			}
		}
		break;

	case BDC_LINK_STATE_RESUME:
		dev_dbg(bdc->dev, "Resumed from Suspend\n");
		if (bdc->devstatus & DEVICE_SUSPENDED) {
			bdc->gadget_driver->resume(&bdc->gadget);
			bdc->devstatus &= ~DEVICE_SUSPENDED;
		}
		break;
	default:
		dev_dbg(bdc->dev, "link state:%d\n", link_state);
	}
}

/* something changes on upstream port, handle it here */
void bdc_sr_uspc(struct bdc *bdc, struct bdc_sr *sreport)
{
	u32 clear_flags = 0;
	u32 uspc;
	bool connected = false;
	bool disconn = false;

	uspc = bdc_readl(bdc->regs, BDC_USPC);
	dev_dbg(bdc->dev, "%s uspc=0x%08x\n", __func__, uspc);

	/* Port connect changed */
	if (uspc & BDC_PCC) {
		/* Vbus not present, and not connected to Downstream port */
		if ((uspc & BDC_VBC) && !(uspc & BDC_VBS) && !(uspc & BDC_PCS))
			disconn = true;
		else if ((uspc & BDC_PCS) && !BDC_PST(uspc))
			connected = true;
		clear_flags |= BDC_PCC;
	}

	/* Change in VBus and VBus is present */
	if ((uspc & BDC_VBC) && (uspc & BDC_VBS)) {
		if (bdc->pullup) {
			dev_dbg(bdc->dev, "Do a softconnect\n");
			/* Attached state, do a softconnect */
			bdc_softconn(bdc);
			usb_gadget_set_state(&bdc->gadget, USB_STATE_POWERED);
		}
		clear_flags |= BDC_VBC;
	} else if ((uspc & BDC_PRS) || (uspc & BDC_PRC) || disconn) {
		/* Hot reset, warm reset, 2.0 bus reset or disconn */
		dev_dbg(bdc->dev, "Port reset or disconn\n");
		bdc_uspc_disconnected(bdc, disconn);
		clear_flags |= BDC_PRC;
	} else if ((uspc & BDC_PSC) && (uspc & BDC_PCS)) {
		/* Change in Link state */
		handle_link_state_change(bdc, uspc);
		clear_flags |= BDC_PSC;
	}

	/*
	 * In SS we might not have PRC bit set before connection, but in 2.0
	 * the PRC bit is set before connection, so moving this condition out
	 * of bus reset to handle both SS/2.0 speeds.
	 */
	if (connected) {
		/* This is the connect event for U0/L0 */
		dev_dbg(bdc->dev, "Connected\n");
		bdc_uspc_connected(bdc);
		bdc->devstatus &= ~(DEVICE_SUSPENDED);
	}
	uspc = bdc_readl(bdc->regs, BDC_USPC);
	uspc &= (~BDC_USPSC_RW);
	dev_dbg(bdc->dev, "uspc=%x\n", uspc);
	bdc_writel(bdc->regs, BDC_USPC, clear_flags);
}

/* Main interrupt handler for bdc */
static irqreturn_t bdc_udc_interrupt(int irq, void *_bdc)
{
	u32 eqp_index, dqp_index, sr_type, srr_int;
	struct bdc_sr *sreport;
	struct bdc *bdc = _bdc;
	u32 status;
	int ret;

	spin_lock(&bdc->lock);
	status = bdc_readl(bdc->regs, BDC_BDCSC);
	if (!(status & BDC_GIP)) {
		spin_unlock(&bdc->lock);
		return IRQ_NONE;
	}
	srr_int = bdc_readl(bdc->regs, BDC_SRRINT(0));
	/* Check if the SRR IP bit it set? */
	if (!(srr_int & BDC_SRR_IP)) {
		dev_warn(bdc->dev, "Global irq pending but SRR IP is 0\n");
		spin_unlock(&bdc->lock);
		return IRQ_NONE;
	}
	eqp_index = BDC_SRR_EPI(srr_int);
	dqp_index = BDC_SRR_DPI(srr_int);
	dev_dbg(bdc->dev,
			"%s eqp_index=%d dqp_index=%d  srr.dqp_index=%d\n\n",
			 __func__, eqp_index, dqp_index, bdc->srr.dqp_index);

	/* check for ring empty condition */
	if (eqp_index == dqp_index) {
		dev_dbg(bdc->dev, "SRR empty?\n");
		spin_unlock(&bdc->lock);
		return IRQ_HANDLED;
	}

	while (bdc->srr.dqp_index != eqp_index) {
		sreport = &bdc->srr.sr_bds[bdc->srr.dqp_index];
		/* sreport is read before using it */
		rmb();
		sr_type = le32_to_cpu(sreport->offset[3]) & BD_TYPE_BITMASK;
		dev_dbg_ratelimited(bdc->dev, "sr_type=%d\n", sr_type);
		switch (sr_type) {
		case SR_XSF:
			bdc->sr_handler[0](bdc, sreport);
			break;

		case SR_USPC:
			bdc->sr_handler[1](bdc, sreport);
			break;
		default:
			dev_warn(bdc->dev, "SR:%d not handled\n", sr_type);
		}
		/* Advance the srr dqp index */
		srr_dqp_index_advc(bdc, 0);
	}
	/* update the hw dequeue pointer */
	srr_int = bdc_readl(bdc->regs, BDC_SRRINT(0));
	srr_int &= ~BDC_SRR_DPI_MASK;
	srr_int &= ~(BDC_SRR_RWS|BDC_SRR_RST|BDC_SRR_ISR);
	srr_int |= ((bdc->srr.dqp_index) << 16);
	srr_int |= BDC_SRR_IP;
	bdc_writel(bdc->regs, BDC_SRRINT(0), srr_int);
	srr_int = bdc_readl(bdc->regs, BDC_SRRINT(0));
	if (bdc->reinit) {
		ret = bdc_reinit(bdc);
		if (ret)
			dev_err(bdc->dev, "err in bdc reinit\n");
	}

	spin_unlock(&bdc->lock);

	return IRQ_HANDLED;
}

/* Gadget ops */
static int bdc_udc_start(struct usb_gadget *gadget,
				struct usb_gadget_driver *driver)
{
	struct bdc *bdc = gadget_to_bdc(gadget);
	unsigned long flags;
	int ret = 0;

	dev_dbg(bdc->dev, "%s()\n", __func__);
	spin_lock_irqsave(&bdc->lock, flags);
	if (bdc->gadget_driver) {
		dev_err(bdc->dev, "%s is already bound to %s\n",
			bdc->gadget.name,
			bdc->gadget_driver->driver.name);
		ret = -EBUSY;
		goto err;
	}
	/*
	 * Run the controller from here and when BDC is connected to
	 * Host then driver will receive a USPC SR with VBUS present
	 * and then driver will do a softconnect.
	*/
	ret = bdc_run(bdc);
	if (ret) {
		dev_err(bdc->dev, "%s bdc run fail\n", __func__);
		goto err;
	}
	bdc->gadget_driver = driver;
	bdc->gadget.dev.driver = &driver->driver;
err:
	spin_unlock_irqrestore(&bdc->lock, flags);

	return ret;
}

static int bdc_udc_stop(struct usb_gadget *gadget)
{
	struct bdc *bdc = gadget_to_bdc(gadget);
	unsigned long flags;

	dev_dbg(bdc->dev, "%s()\n", __func__);
	spin_lock_irqsave(&bdc->lock, flags);
	bdc_stop(bdc);
	bdc->gadget_driver = NULL;
	bdc->gadget.dev.driver = NULL;
	spin_unlock_irqrestore(&bdc->lock, flags);

	return 0;
}

static int bdc_udc_pullup(struct usb_gadget *gadget, int is_on)
{
	struct bdc *bdc = gadget_to_bdc(gadget);
	unsigned long flags;
	u32 uspc;

	dev_dbg(bdc->dev, "%s() is_on:%d\n", __func__, is_on);
	if (!gadget)
		return -EINVAL;

	spin_lock_irqsave(&bdc->lock, flags);
	if (!is_on) {
		bdc_softdisconn(bdc);
		bdc->pullup = false;
	} else {
		/*
		 * For a self powered device, we need to wait till we receive
		 * a VBUS change and Vbus present event, then if pullup flag
		 * is set, then only we present the Termintation.
		 */
		bdc->pullup = true;
		/*
		 * Check if BDC is already connected to Host i.e Vbus=1,
		 * if yes, then present TERM now, this is typical for bus
		 * powered devices.
		 */
		uspc = bdc_readl(bdc->regs, BDC_USPC);
		if (uspc & BDC_VBS)
			bdc_softconn(bdc);
	}
	spin_unlock_irqrestore(&bdc->lock, flags);

	return 0;
}

static int bdc_udc_set_selfpowered(struct usb_gadget *gadget,
		int is_self)
{
	struct bdc		*bdc = gadget_to_bdc(gadget);
	unsigned long           flags;

	dev_dbg(bdc->dev, "%s()\n", __func__);
	gadget->is_selfpowered = (is_self != 0);
	spin_lock_irqsave(&bdc->lock, flags);
	if (!is_self)
		bdc->devstatus |= 1 << USB_DEVICE_SELF_POWERED;
	else
		bdc->devstatus &= ~(1 << USB_DEVICE_SELF_POWERED);

	spin_unlock_irqrestore(&bdc->lock, flags);

	return 0;
}

static int bdc_udc_wakeup(struct usb_gadget *gadget)
{
	struct bdc *bdc = gadget_to_bdc(gadget);
	unsigned long		flags;
	u8	link_state;
	u32	uspc;
	int ret = 0;

	dev_dbg(bdc->dev,
		"%s() bdc->devstatus=%08x\n",
		__func__, bdc->devstatus);

	if (!(bdc->devstatus & REMOTE_WAKE_ENABLE))
		return  -EOPNOTSUPP;

	spin_lock_irqsave(&bdc->lock, flags);
	uspc = bdc_readl(bdc->regs, BDC_USPC);
	link_state = BDC_PST(uspc);
	dev_dbg(bdc->dev, "link_state =%d portsc=%x", link_state, uspc);
	if (link_state != BDC_LINK_STATE_U3) {
		dev_warn(bdc->dev,
			"can't wakeup from link state %d\n",
			link_state);
		ret = -EINVAL;
		goto out;
	}
	if (bdc->gadget.speed == USB_SPEED_SUPER)
		bdc->devstatus |= REMOTE_WAKEUP_ISSUED;

	uspc &= ~BDC_PST_MASK;
	uspc &= (~BDC_USPSC_RW);
	uspc |=  BDC_PST(BDC_LINK_STATE_U0);
	uspc |=  BDC_SWS;
	bdc_writel(bdc->regs, BDC_USPC, uspc);
	uspc = bdc_readl(bdc->regs, BDC_USPC);
	link_state = BDC_PST(uspc);
	dev_dbg(bdc->dev, "link_state =%d portsc=%x", link_state, uspc);
out:
	spin_unlock_irqrestore(&bdc->lock, flags);

	return ret;
}

static const struct usb_gadget_ops bdc_gadget_ops = {
	.wakeup = bdc_udc_wakeup,
	.set_selfpowered = bdc_udc_set_selfpowered,
	.pullup = bdc_udc_pullup,
	.udc_start = bdc_udc_start,
	.udc_stop = bdc_udc_stop,
};

/* Init the gadget interface and register the udc */
int bdc_udc_init(struct bdc *bdc)
{
	u32 temp;
	int ret;

	dev_dbg(bdc->dev, "%s()\n", __func__);
	bdc->gadget.ops = &bdc_gadget_ops;
	bdc->gadget.max_speed = USB_SPEED_SUPER;
	bdc->gadget.speed = USB_SPEED_UNKNOWN;
	bdc->gadget.dev.parent = bdc->dev;

	bdc->gadget.sg_supported = false;


	bdc->gadget.name = BRCM_BDC_NAME;
	ret = devm_request_irq(bdc->dev, bdc->irq, bdc_udc_interrupt,
				IRQF_SHARED , BRCM_BDC_NAME, bdc);
	if (ret) {
		dev_err(bdc->dev,
			"failed to request irq #%d %d\n",
			bdc->irq, ret);
		return ret;
	}

	ret = bdc_init_ep(bdc);
	if (ret) {
		dev_err(bdc->dev, "bdc init ep fail: %d\n", ret);
		return ret;
	}

	ret = usb_add_gadget_udc(bdc->dev, &bdc->gadget);
	if (ret) {
		dev_err(bdc->dev, "failed to register udc\n");
		goto err0;
	}
	usb_gadget_set_state(&bdc->gadget, USB_STATE_NOTATTACHED);
	bdc->bdc_ep_array[1]->desc = &bdc_gadget_ep0_desc;
	/*
	 * Allocate bd list for ep0 only, ep0 will be enabled on connect
	 * status report when the speed is known
	 */
	ret = bdc_ep_enable(bdc->bdc_ep_array[1]);
	if (ret) {
		dev_err(bdc->dev, "fail to enable %s\n",
						bdc->bdc_ep_array[1]->name);
		goto err1;
	}
	INIT_DELAYED_WORK(&bdc->func_wake_notify, bdc_func_wake_timer);
	/* Enable Interrupts */
	temp = bdc_readl(bdc->regs, BDC_BDCSC);
	temp |= BDC_GIE;
	bdc_writel(bdc->regs, BDC_BDCSC, temp);
	return 0;
err1:
	usb_del_gadget_udc(&bdc->gadget);
err0:
	bdc_free_ep(bdc);

	return ret;
}

void bdc_udc_exit(struct bdc *bdc)
{
	unsigned long flags;

	dev_dbg(bdc->dev, "%s()\n", __func__);
	spin_lock_irqsave(&bdc->lock, flags);
	bdc_ep_disable(bdc->bdc_ep_array[1]);
	spin_unlock_irqrestore(&bdc->lock, flags);

	usb_del_gadget_udc(&bdc->gadget);
	bdc_free_ep(bdc);
}
