// 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);
}
