// SPDX-License-Identifier: GPL-2.0
/*
 * Cadence CDNSP DRD Driver.
 *
 * Copyright (C) 2020 Cadence.
 *
 * Author: Pawel Laszczak <pawell@cadence.com>
 *
 */

#include <linux/moduleparam.h>
#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <linux/iopoll.h>
#include <linux/delay.h>
#include <linux/log2.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/irq.h>
#include <linux/dmi.h>

#include "core.h"
#include "gadget-export.h"
#include "drd.h"
#include "cdnsp-gadget.h"
#include "cdnsp-trace.h"

unsigned int cdnsp_port_speed(unsigned int port_status)
{
	/*Detect gadget speed based on PORTSC register*/
	if (DEV_SUPERSPEEDPLUS(port_status))
		return USB_SPEED_SUPER_PLUS;
	else if (DEV_SUPERSPEED(port_status))
		return USB_SPEED_SUPER;
	else if (DEV_HIGHSPEED(port_status))
		return USB_SPEED_HIGH;
	else if (DEV_FULLSPEED(port_status))
		return USB_SPEED_FULL;

	/* If device is detached then speed will be USB_SPEED_UNKNOWN.*/
	return USB_SPEED_UNKNOWN;
}

/*
 * Given a port state, this function returns a value that would result in the
 * port being in the same state, if the value was written to the port status
 * control register.
 * Save Read Only (RO) bits and save read/write bits where
 * writing a 0 clears the bit and writing a 1 sets the bit (RWS).
 * For all other types (RW1S, RW1CS, RW, and RZ), writing a '0' has no effect.
 */
u32 cdnsp_port_state_to_neutral(u32 state)
{
	/* Save read-only status and port state. */
	return (state & CDNSP_PORT_RO) | (state & CDNSP_PORT_RWS);
}

/**
 * cdnsp_find_next_ext_cap - Find the offset of the extended capabilities
 *                           with capability ID id.
 * @base: PCI MMIO registers base address.
 * @start: Address at which to start looking, (0 or HCC_PARAMS to start at
 *         beginning of list)
 * @id: Extended capability ID to search for.
 *
 * Returns the offset of the next matching extended capability structure.
 * Some capabilities can occur several times,
 * e.g., the EXT_CAPS_PROTOCOL, and this provides a way to find them all.
 */
int cdnsp_find_next_ext_cap(void __iomem *base, u32 start, int id)
{
	u32 offset = start;
	u32 next;
	u32 val;

	if (!start || start == HCC_PARAMS_OFFSET) {
		val = readl(base + HCC_PARAMS_OFFSET);
		if (val == ~0)
			return 0;

		offset = HCC_EXT_CAPS(val) << 2;
		if (!offset)
			return 0;
	}

	do {
		val = readl(base + offset);
		if (val == ~0)
			return 0;

		if (EXT_CAPS_ID(val) == id && offset != start)
			return offset;

		next = EXT_CAPS_NEXT(val);
		offset += next << 2;
	} while (next);

	return 0;
}

void cdnsp_set_link_state(struct cdnsp_device *pdev,
			  __le32 __iomem *port_regs,
			  u32 link_state)
{
	int port_num = 0xFF;
	u32 temp;

	temp = readl(port_regs);
	temp = cdnsp_port_state_to_neutral(temp);
	temp |= PORT_WKCONN_E | PORT_WKDISC_E;
	writel(temp, port_regs);

	temp &= ~PORT_PLS_MASK;
	temp |= PORT_LINK_STROBE | link_state;

	if (pdev->active_port)
		port_num = pdev->active_port->port_num;

	trace_cdnsp_handle_port_status(port_num, readl(port_regs));
	writel(temp, port_regs);
	trace_cdnsp_link_state_changed(port_num, readl(port_regs));
}

static void cdnsp_disable_port(struct cdnsp_device *pdev,
			       __le32 __iomem *port_regs)
{
	u32 temp = cdnsp_port_state_to_neutral(readl(port_regs));

	writel(temp | PORT_PED, port_regs);
}

static void cdnsp_clear_port_change_bit(struct cdnsp_device *pdev,
					__le32 __iomem *port_regs)
{
	u32 portsc = readl(port_regs);

	writel(cdnsp_port_state_to_neutral(portsc) |
	       (portsc & PORT_CHANGE_BITS), port_regs);
}

static void cdnsp_set_chicken_bits_2(struct cdnsp_device *pdev, u32 bit)
{
	__le32 __iomem *reg;
	void __iomem *base;
	u32 offset = 0;

	base = &pdev->cap_regs->hc_capbase;
	offset = cdnsp_find_next_ext_cap(base, offset, D_XEC_PRE_REGS_CAP);
	reg = base + offset + REG_CHICKEN_BITS_2_OFFSET;

	bit = readl(reg) | bit;
	writel(bit, reg);
}

static void cdnsp_clear_chicken_bits_2(struct cdnsp_device *pdev, u32 bit)
{
	__le32 __iomem *reg;
	void __iomem *base;
	u32 offset = 0;

	base = &pdev->cap_regs->hc_capbase;
	offset = cdnsp_find_next_ext_cap(base, offset, D_XEC_PRE_REGS_CAP);
	reg = base + offset + REG_CHICKEN_BITS_2_OFFSET;

	bit = readl(reg) & ~bit;
	writel(bit, reg);
}

/*
 * Disable interrupts and begin the controller halting process.
 */
static void cdnsp_quiesce(struct cdnsp_device *pdev)
{
	u32 halted;
	u32 mask;
	u32 cmd;

	mask = ~(u32)(CDNSP_IRQS);

	halted = readl(&pdev->op_regs->status) & STS_HALT;
	if (!halted)
		mask &= ~(CMD_R_S | CMD_DEVEN);

	cmd = readl(&pdev->op_regs->command);
	cmd &= mask;
	writel(cmd, &pdev->op_regs->command);
}

/*
 * Force controller into halt state.
 *
 * Disable any IRQs and clear the run/stop bit.
 * Controller will complete any current and actively pipelined transactions, and
 * should halt within 16 ms of the run/stop bit being cleared.
 * Read controller Halted bit in the status register to see when the
 * controller is finished.
 */
int cdnsp_halt(struct cdnsp_device *pdev)
{
	int ret;
	u32 val;

	cdnsp_quiesce(pdev);

	ret = readl_poll_timeout_atomic(&pdev->op_regs->status, val,
					val & STS_HALT, 1,
					CDNSP_MAX_HALT_USEC);
	if (ret) {
		dev_err(pdev->dev, "ERROR: Device halt failed\n");
		return ret;
	}

	pdev->cdnsp_state |= CDNSP_STATE_HALTED;

	return 0;
}

/*
 * device controller died, register read returns 0xffffffff, or command never
 * ends.
 */
void cdnsp_died(struct cdnsp_device *pdev)
{
	dev_err(pdev->dev, "ERROR: CDNSP controller not responding\n");
	pdev->cdnsp_state |= CDNSP_STATE_DYING;
	cdnsp_halt(pdev);
}

/*
 * Set the run bit and wait for the device to be running.
 */
static int cdnsp_start(struct cdnsp_device *pdev)
{
	u32 temp;
	int ret;

	temp = readl(&pdev->op_regs->command);
	temp |= (CMD_R_S | CMD_DEVEN);
	writel(temp, &pdev->op_regs->command);

	pdev->cdnsp_state = 0;

	/*
	 * Wait for the STS_HALT Status bit to be 0 to indicate the device is
	 * running.
	 */
	ret = readl_poll_timeout_atomic(&pdev->op_regs->status, temp,
					!(temp & STS_HALT), 1,
					CDNSP_MAX_HALT_USEC);
	if (ret) {
		pdev->cdnsp_state = CDNSP_STATE_DYING;
		dev_err(pdev->dev, "ERROR: Controller run failed\n");
	}

	return ret;
}

/*
 * Reset a halted controller.
 *
 * This resets pipelines, timers, counters, state machines, etc.
 * Transactions will be terminated immediately, and operational registers
 * will be set to their defaults.
 */
int cdnsp_reset(struct cdnsp_device *pdev)
{
	u32 command;
	u32 temp;
	int ret;

	temp = readl(&pdev->op_regs->status);

	if (temp == ~(u32)0) {
		dev_err(pdev->dev, "Device not accessible, reset failed.\n");
		return -ENODEV;
	}

	if ((temp & STS_HALT) == 0) {
		dev_err(pdev->dev, "Controller not halted, aborting reset.\n");
		return -EINVAL;
	}

	command = readl(&pdev->op_regs->command);
	command |= CMD_RESET;
	writel(command, &pdev->op_regs->command);

	ret = readl_poll_timeout_atomic(&pdev->op_regs->command, temp,
					!(temp & CMD_RESET), 1,
					10 * 1000);
	if (ret) {
		dev_err(pdev->dev, "ERROR: Controller reset failed\n");
		return ret;
	}

	/*
	 * CDNSP cannot write any doorbells or operational registers other
	 * than status until the "Controller Not Ready" flag is cleared.
	 */
	ret = readl_poll_timeout_atomic(&pdev->op_regs->status, temp,
					!(temp & STS_CNR), 1,
					10 * 1000);

	if (ret) {
		dev_err(pdev->dev, "ERROR: Controller not ready to work\n");
		return ret;
	}

	dev_dbg(pdev->dev, "Controller ready to work");

	return ret;
}

/*
 * cdnsp_get_endpoint_index - Find the index for an endpoint given its
 * descriptor.Use the return value to right shift 1 for the bitmask.
 *
 * Index = (epnum * 2) + direction - 1,
 * where direction = 0 for OUT, 1 for IN.
 * For control endpoints, the IN index is used (OUT index is unused), so
 * index = (epnum * 2) + direction - 1 = (epnum * 2) + 1 - 1 = (epnum * 2)
 */
static unsigned int
	cdnsp_get_endpoint_index(const struct usb_endpoint_descriptor *desc)
{
	unsigned int index = (unsigned int)usb_endpoint_num(desc);

	if (usb_endpoint_xfer_control(desc))
		return index * 2;

	return (index * 2) + (usb_endpoint_dir_in(desc) ? 1 : 0) - 1;
}

/*
 * Find the flag for this endpoint (for use in the control context). Use the
 * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is
 * bit 1, etc.
 */
static unsigned int
	cdnsp_get_endpoint_flag(const struct usb_endpoint_descriptor *desc)
{
	return 1 << (cdnsp_get_endpoint_index(desc) + 1);
}

int cdnsp_ep_enqueue(struct cdnsp_ep *pep, struct cdnsp_request *preq)
{
	struct cdnsp_device *pdev = pep->pdev;
	struct usb_request *request;
	int ret;

	if (preq->epnum == 0 && !list_empty(&pep->pending_list)) {
		trace_cdnsp_request_enqueue_busy(preq);
		return -EBUSY;
	}

	request = &preq->request;
	request->actual = 0;
	request->status = -EINPROGRESS;
	preq->direction = pep->direction;
	preq->epnum = pep->number;
	preq->td.drbl = 0;

	ret = usb_gadget_map_request_by_dev(pdev->dev, request, pep->direction);
	if (ret) {
		trace_cdnsp_request_enqueue_error(preq);
		return ret;
	}

	list_add_tail(&preq->list, &pep->pending_list);

	trace_cdnsp_request_enqueue(preq);

	switch (usb_endpoint_type(pep->endpoint.desc)) {
	case USB_ENDPOINT_XFER_CONTROL:
		ret = cdnsp_queue_ctrl_tx(pdev, preq);
		break;
	case USB_ENDPOINT_XFER_BULK:
	case USB_ENDPOINT_XFER_INT:
		ret = cdnsp_queue_bulk_tx(pdev, preq);
		break;
	case USB_ENDPOINT_XFER_ISOC:
		ret = cdnsp_queue_isoc_tx(pdev, preq);
	}

	if (ret)
		goto unmap;

	return 0;

unmap:
	usb_gadget_unmap_request_by_dev(pdev->dev, &preq->request,
					pep->direction);
	list_del(&preq->list);
	trace_cdnsp_request_enqueue_error(preq);

	return ret;
}

/*
 * Remove the request's TD from the endpoint ring. This may cause the
 * controller to stop USB transfers, potentially stopping in the middle of a
 * TRB buffer. The controller should pick up where it left off in the TD,
 * unless a Set Transfer Ring Dequeue Pointer is issued.
 *
 * The TRBs that make up the buffers for the canceled request will be "removed"
 * from the ring. Since the ring is a contiguous structure, they can't be
 * physically removed. Instead, there are two options:
 *
 *  1) If the controller is in the middle of processing the request to be
 *     canceled, we simply move the ring's dequeue pointer past those TRBs
 *     using the Set Transfer Ring Dequeue Pointer command. This will be
 *     the common case, when drivers timeout on the last submitted request
 *     and attempt to cancel.
 *
 *  2) If the controller is in the middle of a different TD, we turn the TRBs
 *     into a series of 1-TRB transfer no-op TDs. No-ops shouldn't be chained.
 *     The controller will need to invalidate the any TRBs it has cached after
 *     the stop endpoint command.
 *
 *  3) The TD may have completed by the time the Stop Endpoint Command
 *     completes, so software needs to handle that case too.
 *
 */
int cdnsp_ep_dequeue(struct cdnsp_ep *pep, struct cdnsp_request *preq)
{
	struct cdnsp_device *pdev = pep->pdev;
	int ret_stop = 0;
	int ret_rem;

	trace_cdnsp_request_dequeue(preq);

	if (GET_EP_CTX_STATE(pep->out_ctx) == EP_STATE_RUNNING)
		ret_stop = cdnsp_cmd_stop_ep(pdev, pep);

	ret_rem = cdnsp_remove_request(pdev, preq, pep);

	return ret_rem ? ret_rem : ret_stop;
}

static void cdnsp_zero_in_ctx(struct cdnsp_device *pdev)
{
	struct cdnsp_input_control_ctx *ctrl_ctx;
	struct cdnsp_slot_ctx *slot_ctx;
	struct cdnsp_ep_ctx *ep_ctx;
	int i;

	ctrl_ctx = cdnsp_get_input_control_ctx(&pdev->in_ctx);

	/*
	 * When a device's add flag and drop flag are zero, any subsequent
	 * configure endpoint command will leave that endpoint's state
	 * untouched. Make sure we don't leave any old state in the input
	 * endpoint contexts.
	 */
	ctrl_ctx->drop_flags = 0;
	ctrl_ctx->add_flags = 0;
	slot_ctx = cdnsp_get_slot_ctx(&pdev->in_ctx);
	slot_ctx->dev_info &= cpu_to_le32(~LAST_CTX_MASK);

	/* Endpoint 0 is always valid */
	slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1));
	for (i = 1; i < CDNSP_ENDPOINTS_NUM; ++i) {
		ep_ctx = cdnsp_get_ep_ctx(&pdev->in_ctx, i);
		ep_ctx->ep_info = 0;
		ep_ctx->ep_info2 = 0;
		ep_ctx->deq = 0;
		ep_ctx->tx_info = 0;
	}
}

/* Issue a configure endpoint command and wait for it to finish. */
static int cdnsp_configure_endpoint(struct cdnsp_device *pdev)
{
	int ret;

	cdnsp_queue_configure_endpoint(pdev, pdev->cmd.in_ctx->dma);
	cdnsp_ring_cmd_db(pdev);
	ret = cdnsp_wait_for_cmd_compl(pdev);
	if (ret) {
		dev_err(pdev->dev,
			"ERR: unexpected command completion code 0x%x.\n", ret);
		return -EINVAL;
	}

	return ret;
}

static void cdnsp_invalidate_ep_events(struct cdnsp_device *pdev,
				       struct cdnsp_ep *pep)
{
	struct cdnsp_segment *segment;
	union cdnsp_trb *event;
	u32 cycle_state;
	u32  data;

	event = pdev->event_ring->dequeue;
	segment = pdev->event_ring->deq_seg;
	cycle_state = pdev->event_ring->cycle_state;

	while (1) {
		data = le32_to_cpu(event->trans_event.flags);

		/* Check the owner of the TRB. */
		if ((data & TRB_CYCLE) != cycle_state)
			break;

		if (TRB_FIELD_TO_TYPE(data) == TRB_TRANSFER &&
		    TRB_TO_EP_ID(data) == (pep->idx + 1)) {
			data |= TRB_EVENT_INVALIDATE;
			event->trans_event.flags = cpu_to_le32(data);
		}

		if (cdnsp_last_trb_on_seg(segment, event)) {
			cycle_state ^= 1;
			segment = pdev->event_ring->deq_seg->next;
			event = segment->trbs;
		} else {
			event++;
		}
	}
}

int cdnsp_wait_for_cmd_compl(struct cdnsp_device *pdev)
{
	struct cdnsp_segment *event_deq_seg;
	union cdnsp_trb *cmd_trb;
	dma_addr_t cmd_deq_dma;
	union cdnsp_trb *event;
	u32 cycle_state;
	int ret, val;
	u64 cmd_dma;
	u32  flags;

	cmd_trb = pdev->cmd.command_trb;
	pdev->cmd.status = 0;

	trace_cdnsp_cmd_wait_for_compl(pdev->cmd_ring, &cmd_trb->generic);

	ret = readl_poll_timeout_atomic(&pdev->op_regs->cmd_ring, val,
					!CMD_RING_BUSY(val), 1,
					CDNSP_CMD_TIMEOUT);
	if (ret) {
		dev_err(pdev->dev, "ERR: Timeout while waiting for command\n");
		trace_cdnsp_cmd_timeout(pdev->cmd_ring, &cmd_trb->generic);
		pdev->cdnsp_state = CDNSP_STATE_DYING;
		return -ETIMEDOUT;
	}

	event = pdev->event_ring->dequeue;
	event_deq_seg = pdev->event_ring->deq_seg;
	cycle_state = pdev->event_ring->cycle_state;

	cmd_deq_dma = cdnsp_trb_virt_to_dma(pdev->cmd_ring->deq_seg, cmd_trb);
	if (!cmd_deq_dma)
		return -EINVAL;

	while (1) {
		flags = le32_to_cpu(event->event_cmd.flags);

		/* Check the owner of the TRB. */
		if ((flags & TRB_CYCLE) != cycle_state)
			return -EINVAL;

		cmd_dma = le64_to_cpu(event->event_cmd.cmd_trb);

		/*
		 * Check whether the completion event is for last queued
		 * command.
		 */
		if (TRB_FIELD_TO_TYPE(flags) != TRB_COMPLETION ||
		    cmd_dma != (u64)cmd_deq_dma) {
			if (!cdnsp_last_trb_on_seg(event_deq_seg, event)) {
				event++;
				continue;
			}

			if (cdnsp_last_trb_on_ring(pdev->event_ring,
						   event_deq_seg, event))
				cycle_state ^= 1;

			event_deq_seg = event_deq_seg->next;
			event = event_deq_seg->trbs;
			continue;
		}

		trace_cdnsp_handle_command(pdev->cmd_ring, &cmd_trb->generic);

		pdev->cmd.status = GET_COMP_CODE(le32_to_cpu(event->event_cmd.status));
		if (pdev->cmd.status == COMP_SUCCESS)
			return 0;

		return -pdev->cmd.status;
	}
}

int cdnsp_halt_endpoint(struct cdnsp_device *pdev,
			struct cdnsp_ep *pep,
			int value)
{
	int ret;

	trace_cdnsp_ep_halt(value ? "Set" : "Clear");

	ret = cdnsp_cmd_stop_ep(pdev, pep);
	if (ret)
		return ret;

	if (value) {
		if (GET_EP_CTX_STATE(pep->out_ctx) == EP_STATE_STOPPED) {
			cdnsp_queue_halt_endpoint(pdev, pep->idx);
			cdnsp_ring_cmd_db(pdev);
			ret = cdnsp_wait_for_cmd_compl(pdev);
		}

		pep->ep_state |= EP_HALTED;
	} else {
		cdnsp_queue_reset_ep(pdev, pep->idx);
		cdnsp_ring_cmd_db(pdev);
		ret = cdnsp_wait_for_cmd_compl(pdev);
		trace_cdnsp_handle_cmd_reset_ep(pep->out_ctx);

		if (ret)
			return ret;

		pep->ep_state &= ~EP_HALTED;

		if (pep->idx != 0 && !(pep->ep_state & EP_WEDGE))
			cdnsp_ring_doorbell_for_active_rings(pdev, pep);

		pep->ep_state &= ~EP_WEDGE;
	}

	return 0;
}

static int cdnsp_update_eps_configuration(struct cdnsp_device *pdev,
					  struct cdnsp_ep *pep)
{
	struct cdnsp_input_control_ctx *ctrl_ctx;
	struct cdnsp_slot_ctx *slot_ctx;
	int ret = 0;
	u32 ep_sts;
	int i;

	ctrl_ctx = cdnsp_get_input_control_ctx(&pdev->in_ctx);

	/* Don't issue the command if there's no endpoints to update. */
	if (ctrl_ctx->add_flags == 0 && ctrl_ctx->drop_flags == 0)
		return 0;

	ctrl_ctx->add_flags |= cpu_to_le32(SLOT_FLAG);
	ctrl_ctx->add_flags &= cpu_to_le32(~EP0_FLAG);
	ctrl_ctx->drop_flags &= cpu_to_le32(~(SLOT_FLAG | EP0_FLAG));

	/* Fix up Context Entries field. Minimum value is EP0 == BIT(1). */
	slot_ctx = cdnsp_get_slot_ctx(&pdev->in_ctx);
	for (i = CDNSP_ENDPOINTS_NUM; i >= 1; i--) {
		__le32 le32 = cpu_to_le32(BIT(i));

		if ((pdev->eps[i - 1].ring && !(ctrl_ctx->drop_flags & le32)) ||
		    (ctrl_ctx->add_flags & le32) || i == 1) {
			slot_ctx->dev_info &= cpu_to_le32(~LAST_CTX_MASK);
			slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(i));
			break;
		}
	}

	ep_sts = GET_EP_CTX_STATE(pep->out_ctx);

	if ((ctrl_ctx->add_flags != cpu_to_le32(SLOT_FLAG) &&
	     ep_sts == EP_STATE_DISABLED) ||
	    (ep_sts != EP_STATE_DISABLED && ctrl_ctx->drop_flags))
		ret = cdnsp_configure_endpoint(pdev);

	trace_cdnsp_configure_endpoint(cdnsp_get_slot_ctx(&pdev->out_ctx));
	trace_cdnsp_handle_cmd_config_ep(pep->out_ctx);

	cdnsp_zero_in_ctx(pdev);

	return ret;
}

/*
 * This submits a Reset Device Command, which will set the device state to 0,
 * set the device address to 0, and disable all the endpoints except the default
 * control endpoint. The USB core should come back and call
 * cdnsp_setup_device(), and then re-set up the configuration.
 */
int cdnsp_reset_device(struct cdnsp_device *pdev)
{
	struct cdnsp_slot_ctx *slot_ctx;
	int slot_state;
	int ret, i;

	slot_ctx = cdnsp_get_slot_ctx(&pdev->in_ctx);
	slot_ctx->dev_info = 0;
	pdev->device_address = 0;

	/* If device is not setup, there is no point in resetting it. */
	slot_ctx = cdnsp_get_slot_ctx(&pdev->out_ctx);
	slot_state = GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state));
	trace_cdnsp_reset_device(slot_ctx);

	if (slot_state <= SLOT_STATE_DEFAULT &&
	    pdev->eps[0].ep_state & EP_HALTED) {
		cdnsp_halt_endpoint(pdev, &pdev->eps[0], 0);
	}

	/*
	 * During Reset Device command controller shall transition the
	 * endpoint ep0 to the Running State.
	 */
	pdev->eps[0].ep_state &= ~(EP_STOPPED | EP_HALTED);
	pdev->eps[0].ep_state |= EP_ENABLED;

	if (slot_state <= SLOT_STATE_DEFAULT)
		return 0;

	cdnsp_queue_reset_device(pdev);
	cdnsp_ring_cmd_db(pdev);
	ret = cdnsp_wait_for_cmd_compl(pdev);

	/*
	 * After Reset Device command all not default endpoints
	 * are in Disabled state.
	 */
	for (i = 1; i < CDNSP_ENDPOINTS_NUM; ++i)
		pdev->eps[i].ep_state |= EP_STOPPED | EP_UNCONFIGURED;

	trace_cdnsp_handle_cmd_reset_dev(slot_ctx);

	if (ret)
		dev_err(pdev->dev, "Reset device failed with error code %d",
			ret);

	return ret;
}

/*
 * Sets the MaxPStreams field and the Linear Stream Array field.
 * Sets the dequeue pointer to the stream context array.
 */
static void cdnsp_setup_streams_ep_input_ctx(struct cdnsp_device *pdev,
					     struct cdnsp_ep_ctx *ep_ctx,
					     struct cdnsp_stream_info *stream_info)
{
	u32 max_primary_streams;

	/* MaxPStreams is the number of stream context array entries, not the
	 * number we're actually using. Must be in 2^(MaxPstreams + 1) format.
	 * fls(0) = 0, fls(0x1) = 1, fls(0x10) = 2, fls(0x100) = 3, etc.
	 */
	max_primary_streams = fls(stream_info->num_stream_ctxs) - 2;
	ep_ctx->ep_info &= cpu_to_le32(~EP_MAXPSTREAMS_MASK);
	ep_ctx->ep_info |= cpu_to_le32(EP_MAXPSTREAMS(max_primary_streams)
				       | EP_HAS_LSA);
	ep_ctx->deq  = cpu_to_le64(stream_info->ctx_array_dma);
}

/*
 * The drivers use this function to prepare a bulk endpoints to use streams.
 *
 * Don't allow the call to succeed if endpoint only supports one stream
 * (which means it doesn't support streams at all).
 */
int cdnsp_alloc_streams(struct cdnsp_device *pdev, struct cdnsp_ep *pep)
{
	unsigned int num_streams = usb_ss_max_streams(pep->endpoint.comp_desc);
	unsigned int num_stream_ctxs;
	int ret;

	if (num_streams ==  0)
		return 0;

	if (num_streams > STREAM_NUM_STREAMS)
		return -EINVAL;

	/*
	 * Add two to the number of streams requested to account for
	 * stream 0 that is reserved for controller usage and one additional
	 * for TASK SET FULL response.
	 */
	num_streams += 2;

	/* The stream context array size must be a power of two */
	num_stream_ctxs = roundup_pow_of_two(num_streams);

	trace_cdnsp_stream_number(pep, num_stream_ctxs, num_streams);

	ret = cdnsp_alloc_stream_info(pdev, pep, num_stream_ctxs, num_streams);
	if (ret)
		return ret;

	cdnsp_setup_streams_ep_input_ctx(pdev, pep->in_ctx, &pep->stream_info);

	pep->ep_state |= EP_HAS_STREAMS;
	pep->stream_info.td_count = 0;
	pep->stream_info.first_prime_det = 0;

	/* Subtract 1 for stream 0, which drivers can't use. */
	return num_streams - 1;
}

int cdnsp_disable_slot(struct cdnsp_device *pdev)
{
	int ret;

	cdnsp_queue_slot_control(pdev, TRB_DISABLE_SLOT);
	cdnsp_ring_cmd_db(pdev);
	ret = cdnsp_wait_for_cmd_compl(pdev);

	pdev->slot_id = 0;
	pdev->active_port = NULL;

	trace_cdnsp_handle_cmd_disable_slot(cdnsp_get_slot_ctx(&pdev->out_ctx));

	memset(pdev->in_ctx.bytes, 0, CDNSP_CTX_SIZE);
	memset(pdev->out_ctx.bytes, 0, CDNSP_CTX_SIZE);

	return ret;
}

int cdnsp_enable_slot(struct cdnsp_device *pdev)
{
	struct cdnsp_slot_ctx *slot_ctx;
	int slot_state;
	int ret;

	/* If device is not setup, there is no point in resetting it */
	slot_ctx = cdnsp_get_slot_ctx(&pdev->out_ctx);
	slot_state = GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state));

	if (slot_state != SLOT_STATE_DISABLED)
		return 0;

	cdnsp_queue_slot_control(pdev, TRB_ENABLE_SLOT);
	cdnsp_ring_cmd_db(pdev);
	ret = cdnsp_wait_for_cmd_compl(pdev);
	if (ret)
		goto show_trace;

	pdev->slot_id = 1;

show_trace:
	trace_cdnsp_handle_cmd_enable_slot(cdnsp_get_slot_ctx(&pdev->out_ctx));

	return ret;
}

/*
 * Issue an Address Device command with BSR=0 if setup is SETUP_CONTEXT_ONLY
 * or with BSR = 1 if set_address is SETUP_CONTEXT_ADDRESS.
 */
int cdnsp_setup_device(struct cdnsp_device *pdev, enum cdnsp_setup_dev setup)
{
	struct cdnsp_input_control_ctx *ctrl_ctx;
	struct cdnsp_slot_ctx *slot_ctx;
	int dev_state = 0;
	int ret;

	if (!pdev->slot_id) {
		trace_cdnsp_slot_id("incorrect");
		return -EINVAL;
	}

	if (!pdev->active_port->port_num)
		return -EINVAL;

	slot_ctx = cdnsp_get_slot_ctx(&pdev->out_ctx);
	dev_state = GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state));

	if (setup == SETUP_CONTEXT_ONLY && dev_state == SLOT_STATE_DEFAULT) {
		trace_cdnsp_slot_already_in_default(slot_ctx);
		return 0;
	}

	slot_ctx = cdnsp_get_slot_ctx(&pdev->in_ctx);
	ctrl_ctx = cdnsp_get_input_control_ctx(&pdev->in_ctx);

	if (!slot_ctx->dev_info || dev_state == SLOT_STATE_DEFAULT) {
		ret = cdnsp_setup_addressable_priv_dev(pdev);
		if (ret)
			return ret;
	}

	cdnsp_copy_ep0_dequeue_into_input_ctx(pdev);

	ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG);
	ctrl_ctx->drop_flags = 0;

	trace_cdnsp_setup_device_slot(slot_ctx);

	cdnsp_queue_address_device(pdev, pdev->in_ctx.dma, setup);
	cdnsp_ring_cmd_db(pdev);
	ret = cdnsp_wait_for_cmd_compl(pdev);

	trace_cdnsp_handle_cmd_addr_dev(cdnsp_get_slot_ctx(&pdev->out_ctx));

	/* Zero the input context control for later use. */
	ctrl_ctx->add_flags = 0;
	ctrl_ctx->drop_flags = 0;

	return ret;
}

void cdnsp_set_usb2_hardware_lpm(struct cdnsp_device *pdev,
				 struct usb_request *req,
				 int enable)
{
	if (pdev->active_port != &pdev->usb2_port || !pdev->gadget.lpm_capable)
		return;

	trace_cdnsp_lpm(enable);

	if (enable)
		writel(PORT_BESL(CDNSP_DEFAULT_BESL) | PORT_L1S_NYET | PORT_HLE,
		       &pdev->active_port->regs->portpmsc);
	else
		writel(PORT_L1S_NYET, &pdev->active_port->regs->portpmsc);
}

static int cdnsp_get_frame(struct cdnsp_device *pdev)
{
	return readl(&pdev->run_regs->microframe_index) >> 3;
}

static int cdnsp_gadget_ep_enable(struct usb_ep *ep,
				  const struct usb_endpoint_descriptor *desc)
{
	struct cdnsp_input_control_ctx *ctrl_ctx;
	struct cdnsp_device *pdev;
	struct cdnsp_ep *pep;
	unsigned long flags;
	u32 added_ctxs;
	int ret;

	if (!ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT ||
	    !desc->wMaxPacketSize)
		return -EINVAL;

	pep = to_cdnsp_ep(ep);
	pdev = pep->pdev;
	pep->ep_state &= ~EP_UNCONFIGURED;

	if (dev_WARN_ONCE(pdev->dev, pep->ep_state & EP_ENABLED,
			  "%s is already enabled\n", pep->name))
		return 0;

	spin_lock_irqsave(&pdev->lock, flags);

	added_ctxs = cdnsp_get_endpoint_flag(desc);
	if (added_ctxs == SLOT_FLAG || added_ctxs == EP0_FLAG) {
		dev_err(pdev->dev, "ERROR: Bad endpoint number\n");
		ret = -EINVAL;
		goto unlock;
	}

	pep->interval = desc->bInterval ? BIT(desc->bInterval - 1) : 0;

	if (pdev->gadget.speed == USB_SPEED_FULL) {
		if (usb_endpoint_type(desc) == USB_ENDPOINT_XFER_INT)
			pep->interval = desc->bInterval << 3;
		if (usb_endpoint_type(desc) == USB_ENDPOINT_XFER_ISOC)
			pep->interval = BIT(desc->bInterval - 1) << 3;
	}

	if (usb_endpoint_type(desc) == USB_ENDPOINT_XFER_ISOC) {
		if (pep->interval > BIT(12)) {
			dev_err(pdev->dev, "bInterval %d not supported\n",
				desc->bInterval);
			ret = -EINVAL;
			goto unlock;
		}
		cdnsp_set_chicken_bits_2(pdev, CHICKEN_XDMA_2_TP_CACHE_DIS);
	}

	ret = cdnsp_endpoint_init(pdev, pep, GFP_ATOMIC);
	if (ret)
		goto unlock;

	ctrl_ctx = cdnsp_get_input_control_ctx(&pdev->in_ctx);
	ctrl_ctx->add_flags = cpu_to_le32(added_ctxs);
	ctrl_ctx->drop_flags = 0;

	ret = cdnsp_update_eps_configuration(pdev, pep);
	if (ret) {
		cdnsp_free_endpoint_rings(pdev, pep);
		goto unlock;
	}

	pep->ep_state |= EP_ENABLED;
	pep->ep_state &= ~EP_STOPPED;

unlock:
	trace_cdnsp_ep_enable_end(pep, 0);
	spin_unlock_irqrestore(&pdev->lock, flags);

	return ret;
}

static int cdnsp_gadget_ep_disable(struct usb_ep *ep)
{
	struct cdnsp_input_control_ctx *ctrl_ctx;
	struct cdnsp_request *preq;
	struct cdnsp_device *pdev;
	struct cdnsp_ep *pep;
	unsigned long flags;
	u32 drop_flag;
	int ret = 0;

	if (!ep)
		return -EINVAL;

	pep = to_cdnsp_ep(ep);
	pdev = pep->pdev;

	spin_lock_irqsave(&pdev->lock, flags);

	if (!(pep->ep_state & EP_ENABLED)) {
		dev_err(pdev->dev, "%s is already disabled\n", pep->name);
		ret = -EINVAL;
		goto finish;
	}

	pep->ep_state |= EP_DIS_IN_RROGRESS;

	/* Endpoint was unconfigured by Reset Device command. */
	if (!(pep->ep_state & EP_UNCONFIGURED))
		cdnsp_cmd_stop_ep(pdev, pep);

	/* Remove all queued USB requests. */
	while (!list_empty(&pep->pending_list)) {
		preq = next_request(&pep->pending_list);
		cdnsp_ep_dequeue(pep, preq);
	}

	cdnsp_invalidate_ep_events(pdev, pep);

	pep->ep_state &= ~EP_DIS_IN_RROGRESS;
	drop_flag = cdnsp_get_endpoint_flag(pep->endpoint.desc);
	ctrl_ctx = cdnsp_get_input_control_ctx(&pdev->in_ctx);
	ctrl_ctx->drop_flags = cpu_to_le32(drop_flag);
	ctrl_ctx->add_flags = 0;

	cdnsp_endpoint_zero(pdev, pep);

	if (!(pep->ep_state & EP_UNCONFIGURED))
		ret = cdnsp_update_eps_configuration(pdev, pep);

	cdnsp_free_endpoint_rings(pdev, pep);

	pep->ep_state &= ~(EP_ENABLED | EP_UNCONFIGURED);
	pep->ep_state |= EP_STOPPED;

finish:
	trace_cdnsp_ep_disable_end(pep, 0);
	spin_unlock_irqrestore(&pdev->lock, flags);

	return ret;
}

static struct usb_request *cdnsp_gadget_ep_alloc_request(struct usb_ep *ep,
							 gfp_t gfp_flags)
{
	struct cdnsp_ep *pep = to_cdnsp_ep(ep);
	struct cdnsp_request *preq;

	preq = kzalloc(sizeof(*preq), gfp_flags);
	if (!preq)
		return NULL;

	preq->epnum = pep->number;
	preq->pep = pep;

	trace_cdnsp_alloc_request(preq);

	return &preq->request;
}

static void cdnsp_gadget_ep_free_request(struct usb_ep *ep,
					 struct usb_request *request)
{
	struct cdnsp_request *preq = to_cdnsp_request(request);

	trace_cdnsp_free_request(preq);
	kfree(preq);
}

static int cdnsp_gadget_ep_queue(struct usb_ep *ep,
				 struct usb_request *request,
				 gfp_t gfp_flags)
{
	struct cdnsp_request *preq;
	struct cdnsp_device *pdev;
	struct cdnsp_ep *pep;
	unsigned long flags;
	int ret;

	if (!request || !ep)
		return -EINVAL;

	pep = to_cdnsp_ep(ep);
	pdev = pep->pdev;

	if (!(pep->ep_state & EP_ENABLED)) {
		dev_err(pdev->dev, "%s: can't queue to disabled endpoint\n",
			pep->name);
		return -EINVAL;
	}

	preq = to_cdnsp_request(request);
	spin_lock_irqsave(&pdev->lock, flags);
	ret = cdnsp_ep_enqueue(pep, preq);
	spin_unlock_irqrestore(&pdev->lock, flags);

	return ret;
}

static int cdnsp_gadget_ep_dequeue(struct usb_ep *ep,
				   struct usb_request *request)
{
	struct cdnsp_ep *pep = to_cdnsp_ep(ep);
	struct cdnsp_device *pdev = pep->pdev;
	unsigned long flags;
	int ret;

	if (request->status != -EINPROGRESS)
		return 0;

	if (!pep->endpoint.desc) {
		dev_err(pdev->dev,
			"%s: can't dequeue to disabled endpoint\n",
			pep->name);
		return -ESHUTDOWN;
	}

	/* Requests has been dequeued during disabling endpoint. */
	if (!(pep->ep_state & EP_ENABLED))
		return 0;

	spin_lock_irqsave(&pdev->lock, flags);
	ret = cdnsp_ep_dequeue(pep, to_cdnsp_request(request));
	spin_unlock_irqrestore(&pdev->lock, flags);

	return ret;
}

static int cdnsp_gadget_ep_set_halt(struct usb_ep *ep, int value)
{
	struct cdnsp_ep *pep = to_cdnsp_ep(ep);
	struct cdnsp_device *pdev = pep->pdev;
	struct cdnsp_request *preq;
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&pdev->lock, flags);

	preq = next_request(&pep->pending_list);
	if (value) {
		if (preq) {
			trace_cdnsp_ep_busy_try_halt_again(pep, 0);
			ret = -EAGAIN;
			goto done;
		}
	}

	ret = cdnsp_halt_endpoint(pdev, pep, value);

done:
	spin_unlock_irqrestore(&pdev->lock, flags);
	return ret;
}

static int cdnsp_gadget_ep_set_wedge(struct usb_ep *ep)
{
	struct cdnsp_ep *pep = to_cdnsp_ep(ep);
	struct cdnsp_device *pdev = pep->pdev;
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&pdev->lock, flags);
	pep->ep_state |= EP_WEDGE;
	ret = cdnsp_halt_endpoint(pdev, pep, 1);
	spin_unlock_irqrestore(&pdev->lock, flags);

	return ret;
}

static const struct usb_ep_ops cdnsp_gadget_ep0_ops = {
	.enable		= cdnsp_gadget_ep_enable,
	.disable	= cdnsp_gadget_ep_disable,
	.alloc_request	= cdnsp_gadget_ep_alloc_request,
	.free_request	= cdnsp_gadget_ep_free_request,
	.queue		= cdnsp_gadget_ep_queue,
	.dequeue	= cdnsp_gadget_ep_dequeue,
	.set_halt	= cdnsp_gadget_ep_set_halt,
	.set_wedge	= cdnsp_gadget_ep_set_wedge,
};

static const struct usb_ep_ops cdnsp_gadget_ep_ops = {
	.enable		= cdnsp_gadget_ep_enable,
	.disable	= cdnsp_gadget_ep_disable,
	.alloc_request	= cdnsp_gadget_ep_alloc_request,
	.free_request	= cdnsp_gadget_ep_free_request,
	.queue		= cdnsp_gadget_ep_queue,
	.dequeue	= cdnsp_gadget_ep_dequeue,
	.set_halt	= cdnsp_gadget_ep_set_halt,
	.set_wedge	= cdnsp_gadget_ep_set_wedge,
};

void cdnsp_gadget_giveback(struct cdnsp_ep *pep,
			   struct cdnsp_request *preq,
			   int status)
{
	struct cdnsp_device *pdev = pep->pdev;

	list_del(&preq->list);

	if (preq->request.status == -EINPROGRESS)
		preq->request.status = status;

	usb_gadget_unmap_request_by_dev(pdev->dev, &preq->request,
					preq->direction);

	trace_cdnsp_request_giveback(preq);

	if (preq != &pdev->ep0_preq) {
		spin_unlock(&pdev->lock);
		usb_gadget_giveback_request(&pep->endpoint, &preq->request);
		spin_lock(&pdev->lock);
	}
}

static struct usb_endpoint_descriptor cdnsp_gadget_ep0_desc = {
	.bLength =		USB_DT_ENDPOINT_SIZE,
	.bDescriptorType =	USB_DT_ENDPOINT,
	.bmAttributes =		USB_ENDPOINT_XFER_CONTROL,
};

static int cdnsp_run(struct cdnsp_device *pdev,
		     enum usb_device_speed speed)
{
	u32 fs_speed = 0;
	u32 temp;
	int ret;

	temp = readl(&pdev->ir_set->irq_control);
	temp &= ~IMOD_INTERVAL_MASK;
	temp |= ((IMOD_DEFAULT_INTERVAL / 250) & IMOD_INTERVAL_MASK);
	writel(temp, &pdev->ir_set->irq_control);

	temp = readl(&pdev->port3x_regs->mode_addr);

	switch (speed) {
	case USB_SPEED_SUPER_PLUS:
		temp |= CFG_3XPORT_SSP_SUPPORT;
		break;
	case USB_SPEED_SUPER:
		temp &= ~CFG_3XPORT_SSP_SUPPORT;
		break;
	case USB_SPEED_HIGH:
		break;
	case USB_SPEED_FULL:
		fs_speed = PORT_REG6_FORCE_FS;
		break;
	default:
		dev_err(pdev->dev, "invalid maximum_speed parameter %d\n",
			speed);
		fallthrough;
	case USB_SPEED_UNKNOWN:
		/* Default to superspeed. */
		speed = USB_SPEED_SUPER;
		break;
	}

	if (speed >= USB_SPEED_SUPER) {
		writel(temp, &pdev->port3x_regs->mode_addr);
		cdnsp_set_link_state(pdev, &pdev->usb3_port.regs->portsc,
				     XDEV_RXDETECT);
	} else {
		cdnsp_disable_port(pdev, &pdev->usb3_port.regs->portsc);
	}

	cdnsp_set_link_state(pdev, &pdev->usb2_port.regs->portsc,
			     XDEV_RXDETECT);

	cdnsp_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);

	writel(PORT_REG6_L1_L0_HW_EN | fs_speed, &pdev->port20_regs->port_reg6);

	ret = cdnsp_start(pdev);
	if (ret) {
		ret = -ENODEV;
		goto err;
	}

	temp = readl(&pdev->op_regs->command);
	temp |= (CMD_INTE);
	writel(temp, &pdev->op_regs->command);

	temp = readl(&pdev->ir_set->irq_pending);
	writel(IMAN_IE_SET(temp), &pdev->ir_set->irq_pending);

	trace_cdnsp_init("Controller ready to work");
	return 0;
err:
	cdnsp_halt(pdev);
	return ret;
}

static int cdnsp_gadget_udc_start(struct usb_gadget *g,
				  struct usb_gadget_driver *driver)
{
	enum usb_device_speed max_speed = driver->max_speed;
	struct cdnsp_device *pdev = gadget_to_cdnsp(g);
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&pdev->lock, flags);
	pdev->gadget_driver = driver;

	/* limit speed if necessary */
	max_speed = min(driver->max_speed, g->max_speed);
	ret = cdnsp_run(pdev, max_speed);

	spin_unlock_irqrestore(&pdev->lock, flags);

	return ret;
}

/*
 * Update Event Ring Dequeue Pointer:
 * - When all events have finished
 * - To avoid "Event Ring Full Error" condition
 */
void cdnsp_update_erst_dequeue(struct cdnsp_device *pdev,
			       union cdnsp_trb *event_ring_deq,
			       u8 clear_ehb)
{
	u64 temp_64;
	dma_addr_t deq;

	temp_64 = cdnsp_read_64(&pdev->ir_set->erst_dequeue);

	/* If necessary, update the HW's version of the event ring deq ptr. */
	if (event_ring_deq != pdev->event_ring->dequeue) {
		deq = cdnsp_trb_virt_to_dma(pdev->event_ring->deq_seg,
					    pdev->event_ring->dequeue);
		temp_64 &= ERST_PTR_MASK;
		temp_64 |= ((u64)deq & (u64)~ERST_PTR_MASK);
	}

	/* Clear the event handler busy flag (RW1C). */
	if (clear_ehb)
		temp_64 |= ERST_EHB;
	else
		temp_64 &= ~ERST_EHB;

	cdnsp_write_64(temp_64, &pdev->ir_set->erst_dequeue);
}

static void cdnsp_clear_cmd_ring(struct cdnsp_device *pdev)
{
	struct cdnsp_segment *seg;
	u64 val_64;
	int i;

	cdnsp_initialize_ring_info(pdev->cmd_ring);

	seg = pdev->cmd_ring->first_seg;
	for (i = 0; i < pdev->cmd_ring->num_segs; i++) {
		memset(seg->trbs, 0,
		       sizeof(union cdnsp_trb) * (TRBS_PER_SEGMENT - 1));
		seg = seg->next;
	}

	/* Set the address in the Command Ring Control register. */
	val_64 = cdnsp_read_64(&pdev->op_regs->cmd_ring);
	val_64 = (val_64 & (u64)CMD_RING_RSVD_BITS) |
		 (pdev->cmd_ring->first_seg->dma & (u64)~CMD_RING_RSVD_BITS) |
		 pdev->cmd_ring->cycle_state;
	cdnsp_write_64(val_64, &pdev->op_regs->cmd_ring);
}

static void cdnsp_consume_all_events(struct cdnsp_device *pdev)
{
	struct cdnsp_segment *event_deq_seg;
	union cdnsp_trb *event_ring_deq;
	union cdnsp_trb *event;
	u32 cycle_bit;

	event_ring_deq = pdev->event_ring->dequeue;
	event_deq_seg = pdev->event_ring->deq_seg;
	event = pdev->event_ring->dequeue;

	/* Update ring dequeue pointer. */
	while (1) {
		cycle_bit = (le32_to_cpu(event->event_cmd.flags) & TRB_CYCLE);

		/* Does the controller or driver own the TRB? */
		if (cycle_bit != pdev->event_ring->cycle_state)
			break;

		cdnsp_inc_deq(pdev, pdev->event_ring);

		if (!cdnsp_last_trb_on_seg(event_deq_seg, event)) {
			event++;
			continue;
		}

		if (cdnsp_last_trb_on_ring(pdev->event_ring, event_deq_seg,
					   event))
			cycle_bit ^= 1;

		event_deq_seg = event_deq_seg->next;
		event = event_deq_seg->trbs;
	}

	cdnsp_update_erst_dequeue(pdev,  event_ring_deq, 1);
}

static void cdnsp_stop(struct cdnsp_device *pdev)
{
	u32 temp;

	/* Remove internally queued request for ep0. */
	if (!list_empty(&pdev->eps[0].pending_list)) {
		struct cdnsp_request *req;

		req = next_request(&pdev->eps[0].pending_list);
		if (req == &pdev->ep0_preq)
			cdnsp_ep_dequeue(&pdev->eps[0], req);
	}

	cdnsp_disable_port(pdev, &pdev->usb2_port.regs->portsc);
	cdnsp_disable_port(pdev, &pdev->usb3_port.regs->portsc);
	cdnsp_disable_slot(pdev);
	cdnsp_halt(pdev);

	temp = readl(&pdev->op_regs->status);
	writel((temp & ~0x1fff) | STS_EINT, &pdev->op_regs->status);
	temp = readl(&pdev->ir_set->irq_pending);
	writel(IMAN_IE_CLEAR(temp), &pdev->ir_set->irq_pending);

	cdnsp_clear_port_change_bit(pdev, &pdev->usb2_port.regs->portsc);
	cdnsp_clear_port_change_bit(pdev, &pdev->usb3_port.regs->portsc);

	/* Clear interrupt line */
	temp = readl(&pdev->ir_set->irq_pending);
	temp |= IMAN_IP;
	writel(temp, &pdev->ir_set->irq_pending);

	cdnsp_consume_all_events(pdev);
	cdnsp_clear_cmd_ring(pdev);

	trace_cdnsp_exit("Controller stopped.");
}

/*
 * Stop controller.
 * This function is called by the gadget core when the driver is removed.
 * Disable slot, disable IRQs, and quiesce the controller.
 */
static int cdnsp_gadget_udc_stop(struct usb_gadget *g)
{
	struct cdnsp_device *pdev = gadget_to_cdnsp(g);
	unsigned long flags;

	spin_lock_irqsave(&pdev->lock, flags);
	cdnsp_stop(pdev);
	pdev->gadget_driver = NULL;
	spin_unlock_irqrestore(&pdev->lock, flags);

	return 0;
}

static int cdnsp_gadget_get_frame(struct usb_gadget *g)
{
	struct cdnsp_device *pdev = gadget_to_cdnsp(g);

	return cdnsp_get_frame(pdev);
}

static void __cdnsp_gadget_wakeup(struct cdnsp_device *pdev)
{
	struct cdnsp_port_regs __iomem *port_regs;
	u32 portpm, portsc;

	port_regs = pdev->active_port->regs;
	portsc = readl(&port_regs->portsc) & PORT_PLS_MASK;

	/* Remote wakeup feature is not enabled by host. */
	if (pdev->gadget.speed < USB_SPEED_SUPER && portsc == XDEV_U2) {
		portpm = readl(&port_regs->portpmsc);

		if (!(portpm & PORT_RWE))
			return;
	}

	if (portsc == XDEV_U3 && !pdev->may_wakeup)
		return;

	cdnsp_set_link_state(pdev, &port_regs->portsc, XDEV_U0);

	pdev->cdnsp_state |= CDNSP_WAKEUP_PENDING;
}

static int cdnsp_gadget_wakeup(struct usb_gadget *g)
{
	struct cdnsp_device *pdev = gadget_to_cdnsp(g);
	unsigned long flags;

	spin_lock_irqsave(&pdev->lock, flags);
	__cdnsp_gadget_wakeup(pdev);
	spin_unlock_irqrestore(&pdev->lock, flags);

	return 0;
}

static int cdnsp_gadget_set_selfpowered(struct usb_gadget *g,
					int is_selfpowered)
{
	struct cdnsp_device *pdev = gadget_to_cdnsp(g);
	unsigned long flags;

	spin_lock_irqsave(&pdev->lock, flags);
	g->is_selfpowered = !!is_selfpowered;
	spin_unlock_irqrestore(&pdev->lock, flags);

	return 0;
}

static int cdnsp_gadget_pullup(struct usb_gadget *gadget, int is_on)
{
	struct cdnsp_device *pdev = gadget_to_cdnsp(gadget);
	struct cdns *cdns = dev_get_drvdata(pdev->dev);
	unsigned long flags;

	trace_cdnsp_pullup(is_on);

	/*
	 * Disable events handling while controller is being
	 * enabled/disabled.
	 */
	disable_irq(cdns->dev_irq);
	spin_lock_irqsave(&pdev->lock, flags);

	if (!is_on) {
		cdnsp_reset_device(pdev);
		cdns_clear_vbus(cdns);
	} else {
		cdns_set_vbus(cdns);
	}

	spin_unlock_irqrestore(&pdev->lock, flags);
	enable_irq(cdns->dev_irq);

	return 0;
}

static const struct usb_gadget_ops cdnsp_gadget_ops = {
	.get_frame		= cdnsp_gadget_get_frame,
	.wakeup			= cdnsp_gadget_wakeup,
	.set_selfpowered	= cdnsp_gadget_set_selfpowered,
	.pullup			= cdnsp_gadget_pullup,
	.udc_start		= cdnsp_gadget_udc_start,
	.udc_stop		= cdnsp_gadget_udc_stop,
};

static void cdnsp_get_ep_buffering(struct cdnsp_device *pdev,
				   struct cdnsp_ep *pep)
{
	void __iomem *reg = &pdev->cap_regs->hc_capbase;
	int endpoints;

	reg += cdnsp_find_next_ext_cap(reg, 0, XBUF_CAP_ID);

	if (!pep->direction) {
		pep->buffering = readl(reg + XBUF_RX_TAG_MASK_0_OFFSET);
		pep->buffering_period = readl(reg + XBUF_RX_TAG_MASK_1_OFFSET);
		pep->buffering = (pep->buffering + 1) / 2;
		pep->buffering_period = (pep->buffering_period + 1) / 2;
		return;
	}

	endpoints = HCS_ENDPOINTS(pdev->hcs_params1) / 2;

	/* Set to XBUF_TX_TAG_MASK_0 register. */
	reg += XBUF_TX_CMD_OFFSET + (endpoints * 2 + 2) * sizeof(u32);
	/* Set reg to XBUF_TX_TAG_MASK_N related with this endpoint. */
	reg += pep->number * sizeof(u32) * 2;

	pep->buffering = (readl(reg) + 1) / 2;
	pep->buffering_period = pep->buffering;
}

static int cdnsp_gadget_init_endpoints(struct cdnsp_device *pdev)
{
	int max_streams = HCC_MAX_PSA(pdev->hcc_params);
	struct cdnsp_ep *pep;
	int i;

	INIT_LIST_HEAD(&pdev->gadget.ep_list);

	if (max_streams < STREAM_LOG_STREAMS) {
		dev_err(pdev->dev, "Stream size %d not supported\n",
			max_streams);
		return -EINVAL;
	}

	max_streams = STREAM_LOG_STREAMS;

	for (i = 0; i < CDNSP_ENDPOINTS_NUM; i++) {
		bool direction = !(i & 1); /* Start from OUT endpoint. */
		u8 epnum = ((i + 1) >> 1);

		if (!CDNSP_IF_EP_EXIST(pdev, epnum, direction))
			continue;

		pep = &pdev->eps[i];
		pep->pdev = pdev;
		pep->number = epnum;
		pep->direction = direction; /* 0 for OUT, 1 for IN. */

		/*
		 * Ep0 is bidirectional, so ep0in and ep0out are represented by
		 * pdev->eps[0]
		 */
		if (epnum == 0) {
			snprintf(pep->name, sizeof(pep->name), "ep%d%s",
				 epnum, "BiDir");

			pep->idx = 0;
			usb_ep_set_maxpacket_limit(&pep->endpoint, 512);
			pep->endpoint.maxburst = 1;
			pep->endpoint.ops = &cdnsp_gadget_ep0_ops;
			pep->endpoint.desc = &cdnsp_gadget_ep0_desc;
			pep->endpoint.comp_desc = NULL;
			pep->endpoint.caps.type_control = true;
			pep->endpoint.caps.dir_in = true;
			pep->endpoint.caps.dir_out = true;

			pdev->ep0_preq.epnum = pep->number;
			pdev->ep0_preq.pep = pep;
			pdev->gadget.ep0 = &pep->endpoint;
		} else {
			snprintf(pep->name, sizeof(pep->name), "ep%d%s",
				 epnum, (pep->direction) ? "in" : "out");

			pep->idx =  (epnum * 2 + (direction ? 1 : 0)) - 1;
			usb_ep_set_maxpacket_limit(&pep->endpoint, 1024);

			pep->endpoint.max_streams = max_streams;
			pep->endpoint.ops = &cdnsp_gadget_ep_ops;
			list_add_tail(&pep->endpoint.ep_list,
				      &pdev->gadget.ep_list);

			pep->endpoint.caps.type_iso = true;
			pep->endpoint.caps.type_bulk = true;
			pep->endpoint.caps.type_int = true;

			pep->endpoint.caps.dir_in = direction;
			pep->endpoint.caps.dir_out = !direction;
		}

		pep->endpoint.name = pep->name;
		pep->in_ctx = cdnsp_get_ep_ctx(&pdev->in_ctx, pep->idx);
		pep->out_ctx = cdnsp_get_ep_ctx(&pdev->out_ctx, pep->idx);
		cdnsp_get_ep_buffering(pdev, pep);

		dev_dbg(pdev->dev, "Init %s, MPS: %04x SupType: "
			"CTRL: %s, INT: %s, BULK: %s, ISOC %s, "
			"SupDir IN: %s, OUT: %s\n",
			pep->name, 1024,
			(pep->endpoint.caps.type_control) ? "yes" : "no",
			(pep->endpoint.caps.type_int) ? "yes" : "no",
			(pep->endpoint.caps.type_bulk) ? "yes" : "no",
			(pep->endpoint.caps.type_iso) ? "yes" : "no",
			(pep->endpoint.caps.dir_in) ? "yes" : "no",
			(pep->endpoint.caps.dir_out) ? "yes" : "no");

		INIT_LIST_HEAD(&pep->pending_list);
	}

	return 0;
}

static void cdnsp_gadget_free_endpoints(struct cdnsp_device *pdev)
{
	struct cdnsp_ep *pep;
	int i;

	for (i = 0; i < CDNSP_ENDPOINTS_NUM; i++) {
		pep = &pdev->eps[i];
		if (pep->number != 0 && pep->out_ctx)
			list_del(&pep->endpoint.ep_list);
	}
}

void cdnsp_disconnect_gadget(struct cdnsp_device *pdev)
{
	pdev->cdnsp_state |= CDNSP_STATE_DISCONNECT_PENDING;

	if (pdev->gadget_driver && pdev->gadget_driver->disconnect) {
		spin_unlock(&pdev->lock);
		pdev->gadget_driver->disconnect(&pdev->gadget);
		spin_lock(&pdev->lock);
	}

	pdev->gadget.speed = USB_SPEED_UNKNOWN;
	usb_gadget_set_state(&pdev->gadget, USB_STATE_NOTATTACHED);

	pdev->cdnsp_state &= ~CDNSP_STATE_DISCONNECT_PENDING;
}

void cdnsp_suspend_gadget(struct cdnsp_device *pdev)
{
	if (pdev->gadget_driver && pdev->gadget_driver->suspend) {
		spin_unlock(&pdev->lock);
		pdev->gadget_driver->suspend(&pdev->gadget);
		spin_lock(&pdev->lock);
	}
}

void cdnsp_resume_gadget(struct cdnsp_device *pdev)
{
	if (pdev->gadget_driver && pdev->gadget_driver->resume) {
		spin_unlock(&pdev->lock);
		pdev->gadget_driver->resume(&pdev->gadget);
		spin_lock(&pdev->lock);
	}
}

void cdnsp_irq_reset(struct cdnsp_device *pdev)
{
	struct cdnsp_port_regs __iomem *port_regs;

	cdnsp_reset_device(pdev);

	port_regs = pdev->active_port->regs;
	pdev->gadget.speed = cdnsp_port_speed(readl(port_regs));

	spin_unlock(&pdev->lock);
	usb_gadget_udc_reset(&pdev->gadget, pdev->gadget_driver);
	spin_lock(&pdev->lock);

	switch (pdev->gadget.speed) {
	case USB_SPEED_SUPER_PLUS:
	case USB_SPEED_SUPER:
		cdnsp_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);
		pdev->gadget.ep0->maxpacket = 512;
		break;
	case USB_SPEED_HIGH:
	case USB_SPEED_FULL:
		cdnsp_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64);
		pdev->gadget.ep0->maxpacket = 64;
		break;
	default:
		/* Low speed is not supported. */
		dev_err(pdev->dev, "Unknown device speed\n");
		break;
	}

	cdnsp_clear_chicken_bits_2(pdev, CHICKEN_XDMA_2_TP_CACHE_DIS);
	cdnsp_setup_device(pdev, SETUP_CONTEXT_ONLY);
	usb_gadget_set_state(&pdev->gadget, USB_STATE_DEFAULT);
}

static void cdnsp_get_rev_cap(struct cdnsp_device *pdev)
{
	void __iomem *reg = &pdev->cap_regs->hc_capbase;

	reg += cdnsp_find_next_ext_cap(reg, 0, RTL_REV_CAP);
	pdev->rev_cap  = reg;

	dev_info(pdev->dev, "Rev: %08x/%08x, eps: %08x, buff: %08x/%08x\n",
		 readl(&pdev->rev_cap->ctrl_revision),
		 readl(&pdev->rev_cap->rtl_revision),
		 readl(&pdev->rev_cap->ep_supported),
		 readl(&pdev->rev_cap->rx_buff_size),
		 readl(&pdev->rev_cap->tx_buff_size));
}

static int cdnsp_gen_setup(struct cdnsp_device *pdev)
{
	int ret;
	u32 reg;

	pdev->cap_regs = pdev->regs;
	pdev->op_regs = pdev->regs +
		HC_LENGTH(readl(&pdev->cap_regs->hc_capbase));
	pdev->run_regs = pdev->regs +
		(readl(&pdev->cap_regs->run_regs_off) & RTSOFF_MASK);

	/* Cache read-only capability registers */
	pdev->hcs_params1 = readl(&pdev->cap_regs->hcs_params1);
	pdev->hcc_params = readl(&pdev->cap_regs->hc_capbase);
	pdev->hci_version = HC_VERSION(pdev->hcc_params);
	pdev->hcc_params = readl(&pdev->cap_regs->hcc_params);

	cdnsp_get_rev_cap(pdev);

	/* Make sure the Device Controller is halted. */
	ret = cdnsp_halt(pdev);
	if (ret)
		return ret;

	/* Reset the internal controller memory state and registers. */
	ret = cdnsp_reset(pdev);
	if (ret)
		return ret;

	/*
	 * Set dma_mask and coherent_dma_mask to 64-bits,
	 * if controller supports 64-bit addressing.
	 */
	if (HCC_64BIT_ADDR(pdev->hcc_params) &&
	    !dma_set_mask(pdev->dev, DMA_BIT_MASK(64))) {
		dev_dbg(pdev->dev, "Enabling 64-bit DMA addresses.\n");
		dma_set_coherent_mask(pdev->dev, DMA_BIT_MASK(64));
	} else {
		/*
		 * This is to avoid error in cases where a 32-bit USB
		 * controller is used on a 64-bit capable system.
		 */
		ret = dma_set_mask(pdev->dev, DMA_BIT_MASK(32));
		if (ret)
			return ret;

		dev_dbg(pdev->dev, "Enabling 32-bit DMA addresses.\n");
		dma_set_coherent_mask(pdev->dev, DMA_BIT_MASK(32));
	}

	spin_lock_init(&pdev->lock);

	ret = cdnsp_mem_init(pdev);
	if (ret)
		return ret;

	/*
	 * Software workaround for U1: after transition
	 * to U1 the controller starts gating clock, and in some cases,
	 * it causes that controller stack.
	 */
	reg = readl(&pdev->port3x_regs->mode_2);
	reg &= ~CFG_3XPORT_U1_PIPE_CLK_GATE_EN;
	writel(reg, &pdev->port3x_regs->mode_2);

	return 0;
}

static int __cdnsp_gadget_init(struct cdns *cdns)
{
	struct cdnsp_device *pdev;
	u32 max_speed;
	int ret = -ENOMEM;

	cdns_drd_gadget_on(cdns);

	pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
	if (!pdev)
		return -ENOMEM;

	pm_runtime_get_sync(cdns->dev);

	cdns->gadget_dev = pdev;
	pdev->dev = cdns->dev;
	pdev->regs = cdns->dev_regs;
	max_speed = usb_get_maximum_speed(cdns->dev);

	switch (max_speed) {
	case USB_SPEED_FULL:
	case USB_SPEED_HIGH:
	case USB_SPEED_SUPER:
	case USB_SPEED_SUPER_PLUS:
		break;
	default:
		dev_err(cdns->dev, "invalid speed parameter %d\n", max_speed);
		fallthrough;
	case USB_SPEED_UNKNOWN:
		/* Default to SSP */
		max_speed = USB_SPEED_SUPER_PLUS;
		break;
	}

	pdev->gadget.ops = &cdnsp_gadget_ops;
	pdev->gadget.name = "cdnsp-gadget";
	pdev->gadget.speed = USB_SPEED_UNKNOWN;
	pdev->gadget.sg_supported = 1;
	pdev->gadget.max_speed = max_speed;
	pdev->gadget.lpm_capable = 1;

	pdev->setup_buf = kzalloc(CDNSP_EP0_SETUP_SIZE, GFP_KERNEL);
	if (!pdev->setup_buf)
		goto free_pdev;

	/*
	 * Controller supports not aligned buffer but it should improve
	 * performance.
	 */
	pdev->gadget.quirk_ep_out_aligned_size = true;

	ret = cdnsp_gen_setup(pdev);
	if (ret) {
		dev_err(pdev->dev, "Generic initialization failed %d\n", ret);
		goto free_setup;
	}

	ret = cdnsp_gadget_init_endpoints(pdev);
	if (ret) {
		dev_err(pdev->dev, "failed to initialize endpoints\n");
		goto halt_pdev;
	}

	ret = usb_add_gadget_udc(pdev->dev, &pdev->gadget);
	if (ret) {
		dev_err(pdev->dev, "failed to register udc\n");
		goto free_endpoints;
	}

	ret = devm_request_threaded_irq(pdev->dev, cdns->dev_irq,
					cdnsp_irq_handler,
					cdnsp_thread_irq_handler, IRQF_SHARED,
					dev_name(pdev->dev), pdev);
	if (ret)
		goto del_gadget;

	return 0;

del_gadget:
	usb_del_gadget_udc(&pdev->gadget);
free_endpoints:
	cdnsp_gadget_free_endpoints(pdev);
halt_pdev:
	cdnsp_halt(pdev);
	cdnsp_reset(pdev);
	cdnsp_mem_cleanup(pdev);
free_setup:
	kfree(pdev->setup_buf);
free_pdev:
	kfree(pdev);

	return ret;
}

static void cdnsp_gadget_exit(struct cdns *cdns)
{
	struct cdnsp_device *pdev = cdns->gadget_dev;

	devm_free_irq(pdev->dev, cdns->dev_irq, pdev);
	pm_runtime_mark_last_busy(cdns->dev);
	pm_runtime_put_autosuspend(cdns->dev);
	usb_del_gadget_udc(&pdev->gadget);
	cdnsp_gadget_free_endpoints(pdev);
	cdnsp_mem_cleanup(pdev);
	kfree(pdev);
	cdns->gadget_dev = NULL;
	cdns_drd_gadget_off(cdns);
}

static int cdnsp_gadget_suspend(struct cdns *cdns, bool do_wakeup)
{
	struct cdnsp_device *pdev = cdns->gadget_dev;
	unsigned long flags;

	if (pdev->link_state == XDEV_U3)
		return 0;

	spin_lock_irqsave(&pdev->lock, flags);
	cdnsp_disconnect_gadget(pdev);
	cdnsp_stop(pdev);
	spin_unlock_irqrestore(&pdev->lock, flags);

	return 0;
}

static int cdnsp_gadget_resume(struct cdns *cdns, bool hibernated)
{
	struct cdnsp_device *pdev = cdns->gadget_dev;
	enum usb_device_speed max_speed;
	unsigned long flags;
	int ret;

	if (!pdev->gadget_driver)
		return 0;

	spin_lock_irqsave(&pdev->lock, flags);
	max_speed = pdev->gadget_driver->max_speed;

	/* Limit speed if necessary. */
	max_speed = min(max_speed, pdev->gadget.max_speed);

	ret = cdnsp_run(pdev, max_speed);

	if (pdev->link_state == XDEV_U3)
		__cdnsp_gadget_wakeup(pdev);

	spin_unlock_irqrestore(&pdev->lock, flags);

	return ret;
}

/**
 * cdnsp_gadget_init - initialize device structure
 * @cdns: cdnsp instance
 *
 * This function initializes the gadget.
 */
int cdnsp_gadget_init(struct cdns *cdns)
{
	struct cdns_role_driver *rdrv;

	rdrv = devm_kzalloc(cdns->dev, sizeof(*rdrv), GFP_KERNEL);
	if (!rdrv)
		return -ENOMEM;

	rdrv->start	= __cdnsp_gadget_init;
	rdrv->stop	= cdnsp_gadget_exit;
	rdrv->suspend	= cdnsp_gadget_suspend;
	rdrv->resume	= cdnsp_gadget_resume;
	rdrv->state	= CDNS_ROLE_STATE_INACTIVE;
	rdrv->name	= "gadget";
	cdns->roles[USB_ROLE_DEVICE] = rdrv;

	return 0;
}
