// SPDX-License-Identifier: GPL-2.0
/*
 * Cadence CDNSP DRD Driver.
 *
 * Copyright (C) 2020 Cadence.
 *
 * Author: Pawel Laszczak <pawell@cadence.com>
 *
 * Code based on Linux XHCI driver.
 * Origin: Copyright (C) 2008 Intel Corp.
 */

#include <linux/dma-mapping.h>
#include <linux/dmapool.h>
#include <linux/slab.h>
#include <linux/usb.h>

#include "cdnsp-gadget.h"
#include "cdnsp-trace.h"

static void cdnsp_free_stream_info(struct cdnsp_device *pdev,
				   struct cdnsp_ep *pep);
/*
 * Allocates a generic ring segment from the ring pool, sets the dma address,
 * initializes the segment to zero, and sets the private next pointer to NULL.
 *
 * "All components of all Command and Transfer TRBs shall be initialized to '0'"
 */
static struct cdnsp_segment *cdnsp_segment_alloc(struct cdnsp_device *pdev,
						 unsigned int cycle_state,
						 unsigned int max_packet,
						 gfp_t flags)
{
	struct cdnsp_segment *seg;
	dma_addr_t dma;
	int i;

	seg = kzalloc(sizeof(*seg), flags);
	if (!seg)
		return NULL;

	seg->trbs = dma_pool_zalloc(pdev->segment_pool, flags, &dma);
	if (!seg->trbs) {
		kfree(seg);
		return NULL;
	}

	if (max_packet) {
		seg->bounce_buf = kzalloc(max_packet, flags | GFP_DMA);
		if (!seg->bounce_buf)
			goto free_dma;
	}

	/* If the cycle state is 0, set the cycle bit to 1 for all the TRBs. */
	if (cycle_state == 0) {
		for (i = 0; i < TRBS_PER_SEGMENT; i++)
			seg->trbs[i].link.control |= cpu_to_le32(TRB_CYCLE);
	}
	seg->dma = dma;
	seg->next = NULL;

	return seg;

free_dma:
	dma_pool_free(pdev->segment_pool, seg->trbs, dma);
	kfree(seg);

	return NULL;
}

static void cdnsp_segment_free(struct cdnsp_device *pdev,
			       struct cdnsp_segment *seg)
{
	if (seg->trbs)
		dma_pool_free(pdev->segment_pool, seg->trbs, seg->dma);

	kfree(seg->bounce_buf);
	kfree(seg);
}

static void cdnsp_free_segments_for_ring(struct cdnsp_device *pdev,
					 struct cdnsp_segment *first)
{
	struct cdnsp_segment *seg;

	seg = first->next;

	while (seg != first) {
		struct cdnsp_segment *next = seg->next;

		cdnsp_segment_free(pdev, seg);
		seg = next;
	}

	cdnsp_segment_free(pdev, first);
}

/*
 * Make the prev segment point to the next segment.
 *
 * Change the last TRB in the prev segment to be a Link TRB which points to the
 * DMA address of the next segment. The caller needs to set any Link TRB
 * related flags, such as End TRB, Toggle Cycle, and no snoop.
 */
static void cdnsp_link_segments(struct cdnsp_device *pdev,
				struct cdnsp_segment *prev,
				struct cdnsp_segment *next,
				enum cdnsp_ring_type type)
{
	struct cdnsp_link_trb *link;
	u32 val;

	if (!prev || !next)
		return;

	prev->next = next;
	if (type != TYPE_EVENT) {
		link = &prev->trbs[TRBS_PER_SEGMENT - 1].link;
		link->segment_ptr = cpu_to_le64(next->dma);

		/*
		 * Set the last TRB in the segment to have a TRB type ID
		 * of Link TRB
		 */
		val = le32_to_cpu(link->control);
		val &= ~TRB_TYPE_BITMASK;
		val |= TRB_TYPE(TRB_LINK);
		link->control = cpu_to_le32(val);
	}
}

/*
 * Link the ring to the new segments.
 * Set Toggle Cycle for the new ring if needed.
 */
static void cdnsp_link_rings(struct cdnsp_device *pdev,
			     struct cdnsp_ring *ring,
			     struct cdnsp_segment *first,
			     struct cdnsp_segment *last,
			     unsigned int num_segs)
{
	struct cdnsp_segment *next;

	if (!ring || !first || !last)
		return;

	next = ring->enq_seg->next;
	cdnsp_link_segments(pdev, ring->enq_seg, first, ring->type);
	cdnsp_link_segments(pdev, last, next, ring->type);
	ring->num_segs += num_segs;
	ring->num_trbs_free += (TRBS_PER_SEGMENT - 1) * num_segs;

	if (ring->type != TYPE_EVENT && ring->enq_seg == ring->last_seg) {
		ring->last_seg->trbs[TRBS_PER_SEGMENT - 1].link.control &=
			~cpu_to_le32(LINK_TOGGLE);
		last->trbs[TRBS_PER_SEGMENT - 1].link.control |=
			cpu_to_le32(LINK_TOGGLE);
		ring->last_seg = last;
	}
}

/*
 * We need a radix tree for mapping physical addresses of TRBs to which stream
 * ID they belong to. We need to do this because the device controller won't
 * tell us which stream ring the TRB came from. We could store the stream ID
 * in an event data TRB, but that doesn't help us for the cancellation case,
 * since the endpoint may stop before it reaches that event data TRB.
 *
 * The radix tree maps the upper portion of the TRB DMA address to a ring
 * segment that has the same upper portion of DMA addresses. For example,
 * say I have segments of size 1KB, that are always 1KB aligned. A segment may
 * start at 0x10c91000 and end at 0x10c913f0. If I use the upper 10 bits, the
 * key to the stream ID is 0x43244. I can use the DMA address of the TRB to
 * pass the radix tree a key to get the right stream ID:
 *
 *	0x10c90fff >> 10 = 0x43243
 *	0x10c912c0 >> 10 = 0x43244
 *	0x10c91400 >> 10 = 0x43245
 *
 * Obviously, only those TRBs with DMA addresses that are within the segment
 * will make the radix tree return the stream ID for that ring.
 *
 * Caveats for the radix tree:
 *
 * The radix tree uses an unsigned long as a key pair. On 32-bit systems, an
 * unsigned long will be 32-bits; on a 64-bit system an unsigned long will be
 * 64-bits. Since we only request 32-bit DMA addresses, we can use that as the
 * key on 32-bit or 64-bit systems (it would also be fine if we asked for 64-bit
 * PCI DMA addresses on a 64-bit system). There might be a problem on 32-bit
 * extended systems (where the DMA address can be bigger than 32-bits),
 * if we allow the PCI dma mask to be bigger than 32-bits. So don't do that.
 */
static int cdnsp_insert_segment_mapping(struct radix_tree_root *trb_address_map,
					struct cdnsp_ring *ring,
					struct cdnsp_segment *seg,
					gfp_t mem_flags)
{
	unsigned long key;
	int ret;

	key = (unsigned long)(seg->dma >> TRB_SEGMENT_SHIFT);

	/* Skip any segments that were already added. */
	if (radix_tree_lookup(trb_address_map, key))
		return 0;

	ret = radix_tree_maybe_preload(mem_flags);
	if (ret)
		return ret;

	ret = radix_tree_insert(trb_address_map, key, ring);
	radix_tree_preload_end();

	return ret;
}

static void cdnsp_remove_segment_mapping(struct radix_tree_root *trb_address_map,
					 struct cdnsp_segment *seg)
{
	unsigned long key;

	key = (unsigned long)(seg->dma >> TRB_SEGMENT_SHIFT);
	if (radix_tree_lookup(trb_address_map, key))
		radix_tree_delete(trb_address_map, key);
}

static int cdnsp_update_stream_segment_mapping(struct radix_tree_root *trb_address_map,
					       struct cdnsp_ring *ring,
					       struct cdnsp_segment *first_seg,
					       struct cdnsp_segment *last_seg,
					       gfp_t mem_flags)
{
	struct cdnsp_segment *failed_seg;
	struct cdnsp_segment *seg;
	int ret;

	seg = first_seg;
	do {
		ret = cdnsp_insert_segment_mapping(trb_address_map, ring, seg,
						   mem_flags);
		if (ret)
			goto remove_streams;
		if (seg == last_seg)
			return 0;
		seg = seg->next;
	} while (seg != first_seg);

	return 0;

remove_streams:
	failed_seg = seg;
	seg = first_seg;
	do {
		cdnsp_remove_segment_mapping(trb_address_map, seg);
		if (seg == failed_seg)
			return ret;
		seg = seg->next;
	} while (seg != first_seg);

	return ret;
}

static void cdnsp_remove_stream_mapping(struct cdnsp_ring *ring)
{
	struct cdnsp_segment *seg;

	seg = ring->first_seg;
	do {
		cdnsp_remove_segment_mapping(ring->trb_address_map, seg);
		seg = seg->next;
	} while (seg != ring->first_seg);
}

static int cdnsp_update_stream_mapping(struct cdnsp_ring *ring)
{
	return cdnsp_update_stream_segment_mapping(ring->trb_address_map, ring,
			ring->first_seg, ring->last_seg, GFP_ATOMIC);
}

static void cdnsp_ring_free(struct cdnsp_device *pdev, struct cdnsp_ring *ring)
{
	if (!ring)
		return;

	trace_cdnsp_ring_free(ring);

	if (ring->first_seg) {
		if (ring->type == TYPE_STREAM)
			cdnsp_remove_stream_mapping(ring);

		cdnsp_free_segments_for_ring(pdev, ring->first_seg);
	}

	kfree(ring);
}

void cdnsp_initialize_ring_info(struct cdnsp_ring *ring)
{
	ring->enqueue = ring->first_seg->trbs;
	ring->enq_seg = ring->first_seg;
	ring->dequeue = ring->enqueue;
	ring->deq_seg = ring->first_seg;

	/*
	 * The ring is initialized to 0. The producer must write 1 to the cycle
	 * bit to handover ownership of the TRB, so PCS = 1. The consumer must
	 * compare CCS to the cycle bit to check ownership, so CCS = 1.
	 *
	 * New rings are initialized with cycle state equal to 1; if we are
	 * handling ring expansion, set the cycle state equal to the old ring.
	 */
	ring->cycle_state = 1;

	/*
	 * Each segment has a link TRB, and leave an extra TRB for SW
	 * accounting purpose
	 */
	ring->num_trbs_free = ring->num_segs * (TRBS_PER_SEGMENT - 1) - 1;
}

/* Allocate segments and link them for a ring. */
static int cdnsp_alloc_segments_for_ring(struct cdnsp_device *pdev,
					 struct cdnsp_segment **first,
					 struct cdnsp_segment **last,
					 unsigned int num_segs,
					 unsigned int cycle_state,
					 enum cdnsp_ring_type type,
					 unsigned int max_packet,
					 gfp_t flags)
{
	struct cdnsp_segment *prev;

	/* Allocate first segment. */
	prev = cdnsp_segment_alloc(pdev, cycle_state, max_packet, flags);
	if (!prev)
		return -ENOMEM;

	num_segs--;
	*first = prev;

	/* Allocate all other segments. */
	while (num_segs > 0) {
		struct cdnsp_segment	*next;

		next = cdnsp_segment_alloc(pdev, cycle_state,
					   max_packet, flags);
		if (!next) {
			cdnsp_free_segments_for_ring(pdev, *first);
			return -ENOMEM;
		}

		cdnsp_link_segments(pdev, prev, next, type);

		prev = next;
		num_segs--;
	}

	cdnsp_link_segments(pdev, prev, *first, type);
	*last = prev;

	return 0;
}

/*
 * Create a new ring with zero or more segments.
 *
 * Link each segment together into a ring.
 * Set the end flag and the cycle toggle bit on the last segment.
 */
static struct cdnsp_ring *cdnsp_ring_alloc(struct cdnsp_device *pdev,
					   unsigned int num_segs,
					   enum cdnsp_ring_type type,
					   unsigned int max_packet,
					   gfp_t flags)
{
	struct cdnsp_ring *ring;
	int ret;

	ring = kzalloc(sizeof *(ring), flags);
	if (!ring)
		return NULL;

	ring->num_segs = num_segs;
	ring->bounce_buf_len = max_packet;
	INIT_LIST_HEAD(&ring->td_list);
	ring->type = type;

	if (num_segs == 0)
		return ring;

	ret = cdnsp_alloc_segments_for_ring(pdev, &ring->first_seg,
					    &ring->last_seg, num_segs,
					    1, type, max_packet, flags);
	if (ret)
		goto fail;

	/* Only event ring does not use link TRB. */
	if (type != TYPE_EVENT)
		ring->last_seg->trbs[TRBS_PER_SEGMENT - 1].link.control |=
			cpu_to_le32(LINK_TOGGLE);

	cdnsp_initialize_ring_info(ring);
	trace_cdnsp_ring_alloc(ring);
	return ring;
fail:
	kfree(ring);
	return NULL;
}

void cdnsp_free_endpoint_rings(struct cdnsp_device *pdev, struct cdnsp_ep *pep)
{
	cdnsp_ring_free(pdev, pep->ring);
	pep->ring = NULL;
	cdnsp_free_stream_info(pdev, pep);
}

/*
 * Expand an existing ring.
 * Allocate a new ring which has same segment numbers and link the two rings.
 */
int cdnsp_ring_expansion(struct cdnsp_device *pdev,
			 struct cdnsp_ring *ring,
			 unsigned int num_trbs,
			 gfp_t flags)
{
	unsigned int num_segs_needed;
	struct cdnsp_segment *first;
	struct cdnsp_segment *last;
	unsigned int num_segs;
	int ret;

	num_segs_needed = (num_trbs + (TRBS_PER_SEGMENT - 1) - 1) /
			(TRBS_PER_SEGMENT - 1);

	/* Allocate number of segments we needed, or double the ring size. */
	num_segs = max(ring->num_segs, num_segs_needed);

	ret = cdnsp_alloc_segments_for_ring(pdev, &first, &last, num_segs,
					    ring->cycle_state, ring->type,
					    ring->bounce_buf_len, flags);
	if (ret)
		return -ENOMEM;

	if (ring->type == TYPE_STREAM)
		ret = cdnsp_update_stream_segment_mapping(ring->trb_address_map,
							  ring, first,
							  last, flags);

	if (ret) {
		cdnsp_free_segments_for_ring(pdev, first);

		return ret;
	}

	cdnsp_link_rings(pdev, ring, first, last, num_segs);
	trace_cdnsp_ring_expansion(ring);

	return 0;
}

static int cdnsp_init_device_ctx(struct cdnsp_device *pdev)
{
	int size = HCC_64BYTE_CONTEXT(pdev->hcc_params) ? 2048 : 1024;

	pdev->out_ctx.type = CDNSP_CTX_TYPE_DEVICE;
	pdev->out_ctx.size = size;
	pdev->out_ctx.ctx_size = CTX_SIZE(pdev->hcc_params);
	pdev->out_ctx.bytes = dma_pool_zalloc(pdev->device_pool, GFP_ATOMIC,
					      &pdev->out_ctx.dma);

	if (!pdev->out_ctx.bytes)
		return -ENOMEM;

	pdev->in_ctx.type = CDNSP_CTX_TYPE_INPUT;
	pdev->in_ctx.ctx_size = pdev->out_ctx.ctx_size;
	pdev->in_ctx.size = size + pdev->out_ctx.ctx_size;
	pdev->in_ctx.bytes = dma_pool_zalloc(pdev->device_pool, GFP_ATOMIC,
					     &pdev->in_ctx.dma);

	if (!pdev->in_ctx.bytes) {
		dma_pool_free(pdev->device_pool, pdev->out_ctx.bytes,
			      pdev->out_ctx.dma);
		return -ENOMEM;
	}

	return 0;
}

struct cdnsp_input_control_ctx
	*cdnsp_get_input_control_ctx(struct cdnsp_container_ctx *ctx)
{
	if (ctx->type != CDNSP_CTX_TYPE_INPUT)
		return NULL;

	return (struct cdnsp_input_control_ctx *)ctx->bytes;
}

struct cdnsp_slot_ctx *cdnsp_get_slot_ctx(struct cdnsp_container_ctx *ctx)
{
	if (ctx->type == CDNSP_CTX_TYPE_DEVICE)
		return (struct cdnsp_slot_ctx *)ctx->bytes;

	return (struct cdnsp_slot_ctx *)(ctx->bytes + ctx->ctx_size);
}

struct cdnsp_ep_ctx *cdnsp_get_ep_ctx(struct cdnsp_container_ctx *ctx,
				      unsigned int ep_index)
{
	/* Increment ep index by offset of start of ep ctx array. */
	ep_index++;
	if (ctx->type == CDNSP_CTX_TYPE_INPUT)
		ep_index++;

	return (struct cdnsp_ep_ctx *)(ctx->bytes + (ep_index * ctx->ctx_size));
}

static void cdnsp_free_stream_ctx(struct cdnsp_device *pdev,
				  struct cdnsp_ep *pep)
{
	dma_pool_free(pdev->device_pool, pep->stream_info.stream_ctx_array,
		      pep->stream_info.ctx_array_dma);
}

/* The stream context array must be a power of 2. */
static struct cdnsp_stream_ctx
	*cdnsp_alloc_stream_ctx(struct cdnsp_device *pdev, struct cdnsp_ep *pep)
{
	size_t size = sizeof(struct cdnsp_stream_ctx) *
		      pep->stream_info.num_stream_ctxs;

	if (size > CDNSP_CTX_SIZE)
		return NULL;

	/**
	 * Driver uses intentionally the device_pool to allocated stream
	 * context array. Device Pool has 2048 bytes of size what gives us
	 * 128 entries.
	 */
	return dma_pool_zalloc(pdev->device_pool, GFP_DMA32 | GFP_ATOMIC,
			       &pep->stream_info.ctx_array_dma);
}

struct cdnsp_ring *cdnsp_dma_to_transfer_ring(struct cdnsp_ep *pep, u64 address)
{
	if (pep->ep_state & EP_HAS_STREAMS)
		return radix_tree_lookup(&pep->stream_info.trb_address_map,
					 address >> TRB_SEGMENT_SHIFT);

	return pep->ring;
}

/*
 * Change an endpoint's internal structure so it supports stream IDs.
 * The number of requested streams includes stream 0, which cannot be used by
 * driver.
 *
 * The number of stream contexts in the stream context array may be bigger than
 * the number of streams the driver wants to use. This is because the number of
 * stream context array entries must be a power of two.
 */
int cdnsp_alloc_stream_info(struct cdnsp_device *pdev,
			    struct cdnsp_ep *pep,
			    unsigned int num_stream_ctxs,
			    unsigned int num_streams)
{
	struct cdnsp_stream_info *stream_info;
	struct cdnsp_ring *cur_ring;
	u32 cur_stream;
	u64 addr;
	int ret;
	int mps;

	stream_info = &pep->stream_info;
	stream_info->num_streams = num_streams;
	stream_info->num_stream_ctxs = num_stream_ctxs;

	/* Initialize the array of virtual pointers to stream rings. */
	stream_info->stream_rings = kcalloc(num_streams,
					    sizeof(struct cdnsp_ring *),
					    GFP_ATOMIC);
	if (!stream_info->stream_rings)
		return -ENOMEM;

	/* Initialize the array of DMA addresses for stream rings for the HW. */
	stream_info->stream_ctx_array = cdnsp_alloc_stream_ctx(pdev, pep);
	if (!stream_info->stream_ctx_array)
		goto cleanup_stream_rings;

	memset(stream_info->stream_ctx_array, 0,
	       sizeof(struct cdnsp_stream_ctx) * num_stream_ctxs);
	INIT_RADIX_TREE(&stream_info->trb_address_map, GFP_ATOMIC);
	mps = usb_endpoint_maxp(pep->endpoint.desc);

	/*
	 * Allocate rings for all the streams that the driver will use,
	 * and add their segment DMA addresses to the radix tree.
	 * Stream 0 is reserved.
	 */
	for (cur_stream = 1; cur_stream < num_streams; cur_stream++) {
		cur_ring = cdnsp_ring_alloc(pdev, 2, TYPE_STREAM, mps,
					    GFP_ATOMIC);
		stream_info->stream_rings[cur_stream] = cur_ring;

		if (!cur_ring)
			goto cleanup_rings;

		cur_ring->stream_id = cur_stream;
		cur_ring->trb_address_map = &stream_info->trb_address_map;

		/* Set deq ptr, cycle bit, and stream context type. */
		addr = cur_ring->first_seg->dma | SCT_FOR_CTX(SCT_PRI_TR) |
		       cur_ring->cycle_state;

		stream_info->stream_ctx_array[cur_stream].stream_ring =
			cpu_to_le64(addr);

		trace_cdnsp_set_stream_ring(cur_ring);

		ret = cdnsp_update_stream_mapping(cur_ring);
		if (ret)
			goto cleanup_rings;
	}

	return 0;

cleanup_rings:
	for (cur_stream = 1; cur_stream < num_streams; cur_stream++) {
		cur_ring = stream_info->stream_rings[cur_stream];
		if (cur_ring) {
			cdnsp_ring_free(pdev, cur_ring);
			stream_info->stream_rings[cur_stream] = NULL;
		}
	}

cleanup_stream_rings:
	kfree(pep->stream_info.stream_rings);

	return -ENOMEM;
}

/* Frees all stream contexts associated with the endpoint. */
static void cdnsp_free_stream_info(struct cdnsp_device *pdev,
				   struct cdnsp_ep *pep)
{
	struct cdnsp_stream_info *stream_info = &pep->stream_info;
	struct cdnsp_ring *cur_ring;
	int cur_stream;

	if (!(pep->ep_state & EP_HAS_STREAMS))
		return;

	for (cur_stream = 1; cur_stream < stream_info->num_streams;
	     cur_stream++) {
		cur_ring = stream_info->stream_rings[cur_stream];
		if (cur_ring) {
			cdnsp_ring_free(pdev, cur_ring);
			stream_info->stream_rings[cur_stream] = NULL;
		}
	}

	if (stream_info->stream_ctx_array)
		cdnsp_free_stream_ctx(pdev, pep);

	kfree(stream_info->stream_rings);
	pep->ep_state &= ~EP_HAS_STREAMS;
}

/* All the cdnsp_tds in the ring's TD list should be freed at this point.*/
static void cdnsp_free_priv_device(struct cdnsp_device *pdev)
{
	pdev->dcbaa->dev_context_ptrs[1] = 0;

	cdnsp_free_endpoint_rings(pdev, &pdev->eps[0]);

	if (pdev->in_ctx.bytes)
		dma_pool_free(pdev->device_pool, pdev->in_ctx.bytes,
			      pdev->in_ctx.dma);

	if (pdev->out_ctx.bytes)
		dma_pool_free(pdev->device_pool, pdev->out_ctx.bytes,
			      pdev->out_ctx.dma);

	pdev->in_ctx.bytes = NULL;
	pdev->out_ctx.bytes = NULL;
}

static int cdnsp_alloc_priv_device(struct cdnsp_device *pdev)
{
	int ret;

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

	/* Allocate endpoint 0 ring. */
	pdev->eps[0].ring = cdnsp_ring_alloc(pdev, 2, TYPE_CTRL, 0, GFP_ATOMIC);
	if (!pdev->eps[0].ring)
		goto fail;

	/* Point to output device context in dcbaa. */
	pdev->dcbaa->dev_context_ptrs[1] = cpu_to_le64(pdev->out_ctx.dma);
	pdev->cmd.in_ctx = &pdev->in_ctx;

	trace_cdnsp_alloc_priv_device(pdev);
	return 0;
fail:
	dma_pool_free(pdev->device_pool, pdev->out_ctx.bytes,
		      pdev->out_ctx.dma);
	dma_pool_free(pdev->device_pool, pdev->in_ctx.bytes,
		      pdev->in_ctx.dma);

	return ret;
}

void cdnsp_copy_ep0_dequeue_into_input_ctx(struct cdnsp_device *pdev)
{
	struct cdnsp_ep_ctx *ep0_ctx = pdev->eps[0].in_ctx;
	struct cdnsp_ring *ep_ring = pdev->eps[0].ring;
	dma_addr_t dma;

	dma = cdnsp_trb_virt_to_dma(ep_ring->enq_seg, ep_ring->enqueue);
	ep0_ctx->deq = cpu_to_le64(dma | ep_ring->cycle_state);
}

/* Setup an controller private device for a Set Address command. */
int cdnsp_setup_addressable_priv_dev(struct cdnsp_device *pdev)
{
	struct cdnsp_slot_ctx *slot_ctx;
	struct cdnsp_ep_ctx *ep0_ctx;
	u32 max_packets, port;

	ep0_ctx = cdnsp_get_ep_ctx(&pdev->in_ctx, 0);
	slot_ctx = cdnsp_get_slot_ctx(&pdev->in_ctx);

	/* Only the control endpoint is valid - one endpoint context. */
	slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1));

	switch (pdev->gadget.speed) {
	case USB_SPEED_SUPER_PLUS:
		slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_SSP);
		max_packets = MAX_PACKET(512);
		break;
	case USB_SPEED_SUPER:
		slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_SS);
		max_packets = MAX_PACKET(512);
		break;
	case USB_SPEED_HIGH:
		slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_HS);
		max_packets = MAX_PACKET(64);
		break;
	case USB_SPEED_FULL:
		slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_FS);
		max_packets = MAX_PACKET(64);
		break;
	default:
		/* Speed was not set , this shouldn't happen. */
		return -EINVAL;
	}

	port = DEV_PORT(pdev->active_port->port_num);
	slot_ctx->dev_port |= cpu_to_le32(port);
	slot_ctx->dev_state = cpu_to_le32((pdev->device_address &
					   DEV_ADDR_MASK));
	ep0_ctx->tx_info = cpu_to_le32(EP_AVG_TRB_LENGTH(0x8));
	ep0_ctx->ep_info2 = cpu_to_le32(EP_TYPE(CTRL_EP));
	ep0_ctx->ep_info2 |= cpu_to_le32(MAX_BURST(0) | ERROR_COUNT(3) |
					 max_packets);

	ep0_ctx->deq = cpu_to_le64(pdev->eps[0].ring->first_seg->dma |
				   pdev->eps[0].ring->cycle_state);

	trace_cdnsp_setup_addressable_priv_device(pdev);

	return 0;
}

/*
 * Convert interval expressed as 2^(bInterval - 1) == interval into
 * straight exponent value 2^n == interval.
 */
static unsigned int cdnsp_parse_exponent_interval(struct usb_gadget *g,
						  struct cdnsp_ep *pep)
{
	unsigned int interval;

	interval = clamp_val(pep->endpoint.desc->bInterval, 1, 16) - 1;
	if (interval != pep->endpoint.desc->bInterval - 1)
		dev_warn(&g->dev, "ep %s - rounding interval to %d %sframes\n",
			 pep->name, 1 << interval,
			 g->speed == USB_SPEED_FULL ? "" : "micro");

	/*
	 * Full speed isoc endpoints specify interval in frames,
	 * not microframes. We are using microframes everywhere,
	 * so adjust accordingly.
	 */
	if (g->speed == USB_SPEED_FULL)
		interval += 3;	/* 1 frame = 2^3 uframes */

	/* Controller handles only up to 512ms (2^12). */
	if (interval > 12)
		interval = 12;

	return interval;
}

/*
 * Convert bInterval expressed in microframes (in 1-255 range) to exponent of
 * microframes, rounded down to nearest power of 2.
 */
static unsigned int cdnsp_microframes_to_exponent(struct usb_gadget *g,
						  struct cdnsp_ep *pep,
						  unsigned int desc_interval,
						  unsigned int min_exponent,
						  unsigned int max_exponent)
{
	unsigned int interval;

	interval = fls(desc_interval) - 1;
	return clamp_val(interval, min_exponent, max_exponent);
}

/*
 * Return the polling interval.
 *
 * The polling interval is expressed in "microframes". If controllers's Interval
 * field is set to N, it will service the endpoint every 2^(Interval)*125us.
 */
static unsigned int cdnsp_get_endpoint_interval(struct usb_gadget *g,
						struct cdnsp_ep *pep)
{
	unsigned int interval = 0;

	switch (g->speed) {
	case USB_SPEED_HIGH:
	case USB_SPEED_SUPER_PLUS:
	case USB_SPEED_SUPER:
		if (usb_endpoint_xfer_int(pep->endpoint.desc) ||
		    usb_endpoint_xfer_isoc(pep->endpoint.desc))
			interval = cdnsp_parse_exponent_interval(g, pep);
		break;
	case USB_SPEED_FULL:
		if (usb_endpoint_xfer_isoc(pep->endpoint.desc)) {
			interval = cdnsp_parse_exponent_interval(g, pep);
		} else if (usb_endpoint_xfer_int(pep->endpoint.desc)) {
			interval = pep->endpoint.desc->bInterval << 3;
			interval = cdnsp_microframes_to_exponent(g, pep,
								 interval,
								 3, 10);
		}

		break;
	default:
		WARN_ON(1);
	}

	return interval;
}

/*
 * The "Mult" field in the endpoint context is only set for SuperSpeed isoc eps.
 * High speed endpoint descriptors can define "the number of additional
 * transaction opportunities per microframe", but that goes in the Max Burst
 * endpoint context field.
 */
static u32 cdnsp_get_endpoint_mult(struct usb_gadget *g, struct cdnsp_ep *pep)
{
	if (g->speed < USB_SPEED_SUPER ||
	    !usb_endpoint_xfer_isoc(pep->endpoint.desc))
		return 0;

	return pep->endpoint.comp_desc->bmAttributes;
}

static u32 cdnsp_get_endpoint_max_burst(struct usb_gadget *g,
					struct cdnsp_ep *pep)
{
	/* Super speed and Plus have max burst in ep companion desc */
	if (g->speed >= USB_SPEED_SUPER)
		return pep->endpoint.comp_desc->bMaxBurst;

	if (g->speed == USB_SPEED_HIGH &&
	    (usb_endpoint_xfer_isoc(pep->endpoint.desc) ||
	     usb_endpoint_xfer_int(pep->endpoint.desc)))
		return usb_endpoint_maxp_mult(pep->endpoint.desc) - 1;

	return 0;
}

static u32 cdnsp_get_endpoint_type(const struct usb_endpoint_descriptor *desc)
{
	int in;

	in = usb_endpoint_dir_in(desc);

	switch (usb_endpoint_type(desc)) {
	case USB_ENDPOINT_XFER_CONTROL:
		return CTRL_EP;
	case USB_ENDPOINT_XFER_BULK:
		return in ? BULK_IN_EP : BULK_OUT_EP;
	case USB_ENDPOINT_XFER_ISOC:
		return in ? ISOC_IN_EP : ISOC_OUT_EP;
	case USB_ENDPOINT_XFER_INT:
		return in ? INT_IN_EP : INT_OUT_EP;
	}

	return 0;
}

/*
 * Return the maximum endpoint service interval time (ESIT) payload.
 * Basically, this is the maxpacket size, multiplied by the burst size
 * and mult size.
 */
static u32 cdnsp_get_max_esit_payload(struct usb_gadget *g,
				      struct cdnsp_ep *pep)
{
	int max_packet;
	int max_burst;

	/* Only applies for interrupt or isochronous endpoints*/
	if (usb_endpoint_xfer_control(pep->endpoint.desc) ||
	    usb_endpoint_xfer_bulk(pep->endpoint.desc))
		return 0;

	/* SuperSpeedPlus Isoc ep sending over 48k per EIST. */
	if (g->speed >= USB_SPEED_SUPER_PLUS &&
	    USB_SS_SSP_ISOC_COMP(pep->endpoint.desc->bmAttributes))
		return le16_to_cpu(pep->endpoint.comp_desc->wBytesPerInterval);
	/* SuperSpeed or SuperSpeedPlus Isoc ep with less than 48k per esit */
	else if (g->speed >= USB_SPEED_SUPER)
		return le16_to_cpu(pep->endpoint.comp_desc->wBytesPerInterval);

	max_packet = usb_endpoint_maxp(pep->endpoint.desc);
	max_burst = usb_endpoint_maxp_mult(pep->endpoint.desc);

	/* A 0 in max burst means 1 transfer per ESIT */
	return max_packet * max_burst;
}

int cdnsp_endpoint_init(struct cdnsp_device *pdev,
			struct cdnsp_ep *pep,
			gfp_t mem_flags)
{
	enum cdnsp_ring_type ring_type;
	struct cdnsp_ep_ctx *ep_ctx;
	unsigned int err_count = 0;
	unsigned int avg_trb_len;
	unsigned int max_packet;
	unsigned int max_burst;
	unsigned int interval;
	u32 max_esit_payload;
	unsigned int mult;
	u32 endpoint_type;
	int ret;

	ep_ctx = pep->in_ctx;

	endpoint_type = cdnsp_get_endpoint_type(pep->endpoint.desc);
	if (!endpoint_type)
		return -EINVAL;

	ring_type = usb_endpoint_type(pep->endpoint.desc);

	/*
	 * Get values to fill the endpoint context, mostly from ep descriptor.
	 * The average TRB buffer length for bulk endpoints is unclear as we
	 * have no clue on scatter gather list entry size. For Isoc and Int,
	 * set it to max available.
	 */
	max_esit_payload = cdnsp_get_max_esit_payload(&pdev->gadget, pep);
	interval = cdnsp_get_endpoint_interval(&pdev->gadget, pep);
	mult = cdnsp_get_endpoint_mult(&pdev->gadget, pep);
	max_packet = usb_endpoint_maxp(pep->endpoint.desc);
	max_burst = cdnsp_get_endpoint_max_burst(&pdev->gadget, pep);
	avg_trb_len = max_esit_payload;

	/* Allow 3 retries for everything but isoc, set CErr = 3. */
	if (!usb_endpoint_xfer_isoc(pep->endpoint.desc))
		err_count = 3;
	if (usb_endpoint_xfer_bulk(pep->endpoint.desc) &&
	    pdev->gadget.speed == USB_SPEED_HIGH)
		max_packet = 512;
	/* Controller spec indicates that ctrl ep avg TRB Length should be 8. */
	if (usb_endpoint_xfer_control(pep->endpoint.desc))
		avg_trb_len = 8;

	/* Set up the endpoint ring. */
	pep->ring = cdnsp_ring_alloc(pdev, 2, ring_type, max_packet, mem_flags);
	pep->skip = false;

	/* Fill the endpoint context */
	ep_ctx->ep_info = cpu_to_le32(EP_MAX_ESIT_PAYLOAD_HI(max_esit_payload) |
				EP_INTERVAL(interval) | EP_MULT(mult));
	ep_ctx->ep_info2 = cpu_to_le32(EP_TYPE(endpoint_type) |
				MAX_PACKET(max_packet) | MAX_BURST(max_burst) |
				ERROR_COUNT(err_count));
	ep_ctx->deq = cpu_to_le64(pep->ring->first_seg->dma |
				  pep->ring->cycle_state);

	ep_ctx->tx_info = cpu_to_le32(EP_MAX_ESIT_PAYLOAD_LO(max_esit_payload) |
				EP_AVG_TRB_LENGTH(avg_trb_len));

	if (usb_endpoint_xfer_bulk(pep->endpoint.desc) &&
	    pdev->gadget.speed > USB_SPEED_HIGH) {
		ret = cdnsp_alloc_streams(pdev, pep);
		if (ret < 0)
			return ret;
	}

	return 0;
}

void cdnsp_endpoint_zero(struct cdnsp_device *pdev, struct cdnsp_ep *pep)
{
	pep->in_ctx->ep_info = 0;
	pep->in_ctx->ep_info2 = 0;
	pep->in_ctx->deq = 0;
	pep->in_ctx->tx_info = 0;
}

static int cdnsp_alloc_erst(struct cdnsp_device *pdev,
			    struct cdnsp_ring *evt_ring,
			    struct cdnsp_erst *erst)
{
	struct cdnsp_erst_entry *entry;
	struct cdnsp_segment *seg;
	unsigned int val;
	size_t size;

	size = sizeof(struct cdnsp_erst_entry) * evt_ring->num_segs;
	erst->entries = dma_alloc_coherent(pdev->dev, size,
					   &erst->erst_dma_addr, GFP_KERNEL);
	if (!erst->entries)
		return -ENOMEM;

	erst->num_entries = evt_ring->num_segs;

	seg = evt_ring->first_seg;
	for (val = 0; val < evt_ring->num_segs; val++) {
		entry = &erst->entries[val];
		entry->seg_addr = cpu_to_le64(seg->dma);
		entry->seg_size = cpu_to_le32(TRBS_PER_SEGMENT);
		entry->rsvd = 0;
		seg = seg->next;
	}

	return 0;
}

static void cdnsp_free_erst(struct cdnsp_device *pdev, struct cdnsp_erst *erst)
{
	size_t size = sizeof(struct cdnsp_erst_entry) * (erst->num_entries);
	struct device *dev = pdev->dev;

	if (erst->entries)
		dma_free_coherent(dev, size, erst->entries,
				  erst->erst_dma_addr);

	erst->entries = NULL;
}

void cdnsp_mem_cleanup(struct cdnsp_device *pdev)
{
	struct device *dev = pdev->dev;

	cdnsp_free_priv_device(pdev);
	cdnsp_free_erst(pdev, &pdev->erst);

	if (pdev->event_ring)
		cdnsp_ring_free(pdev, pdev->event_ring);

	pdev->event_ring = NULL;

	if (pdev->cmd_ring)
		cdnsp_ring_free(pdev, pdev->cmd_ring);

	pdev->cmd_ring = NULL;

	dma_pool_destroy(pdev->segment_pool);
	pdev->segment_pool = NULL;
	dma_pool_destroy(pdev->device_pool);
	pdev->device_pool = NULL;

	dma_free_coherent(dev, sizeof(*pdev->dcbaa),
			  pdev->dcbaa, pdev->dcbaa->dma);

	pdev->dcbaa = NULL;

	pdev->usb2_port.exist = 0;
	pdev->usb3_port.exist = 0;
	pdev->usb2_port.port_num = 0;
	pdev->usb3_port.port_num = 0;
	pdev->active_port = NULL;
}

static void cdnsp_set_event_deq(struct cdnsp_device *pdev)
{
	dma_addr_t deq;
	u64 temp;

	deq = cdnsp_trb_virt_to_dma(pdev->event_ring->deq_seg,
				    pdev->event_ring->dequeue);

	/* Update controller event ring dequeue pointer */
	temp = cdnsp_read_64(&pdev->ir_set->erst_dequeue);
	temp &= ERST_PTR_MASK;

	/*
	 * Don't clear the EHB bit (which is RW1C) because
	 * there might be more events to service.
	 */
	temp &= ~ERST_EHB;

	cdnsp_write_64(((u64)deq & (u64)~ERST_PTR_MASK) | temp,
		       &pdev->ir_set->erst_dequeue);
}

static void cdnsp_add_in_port(struct cdnsp_device *pdev,
			      struct cdnsp_port *port,
			      __le32 __iomem *addr)
{
	u32 temp, port_offset, port_count;

	temp = readl(addr);
	port->maj_rev = CDNSP_EXT_PORT_MAJOR(temp);
	port->min_rev = CDNSP_EXT_PORT_MINOR(temp);

	/* Port offset and count in the third dword.*/
	temp = readl(addr + 2);
	port_offset = CDNSP_EXT_PORT_OFF(temp);
	port_count = CDNSP_EXT_PORT_COUNT(temp);

	trace_cdnsp_port_info(addr, port_offset, port_count, port->maj_rev);

	port->port_num = port_offset;
	port->exist = 1;
}

/*
 * Scan the Extended Capabilities for the "Supported Protocol Capabilities" that
 * specify what speeds each port is supposed to be.
 */
static int cdnsp_setup_port_arrays(struct cdnsp_device *pdev)
{
	void __iomem *base;
	u32 offset;
	int i;

	base = &pdev->cap_regs->hc_capbase;
	offset = cdnsp_find_next_ext_cap(base, 0,
					 EXT_CAP_CFG_DEV_20PORT_CAP_ID);
	pdev->port20_regs = base + offset;

	offset = cdnsp_find_next_ext_cap(base, 0, D_XEC_CFG_3XPORT_CAP);
	pdev->port3x_regs =  base + offset;

	offset = 0;
	base = &pdev->cap_regs->hc_capbase;

	/* Driver expects max 2 extended protocol capability. */
	for (i = 0; i < 2; i++) {
		u32 temp;

		offset = cdnsp_find_next_ext_cap(base, offset,
						 EXT_CAPS_PROTOCOL);
		temp = readl(base + offset);

		if (CDNSP_EXT_PORT_MAJOR(temp) == 0x03 &&
		    !pdev->usb3_port.port_num)
			cdnsp_add_in_port(pdev, &pdev->usb3_port,
					  base + offset);

		if (CDNSP_EXT_PORT_MAJOR(temp) == 0x02 &&
		    !pdev->usb2_port.port_num)
			cdnsp_add_in_port(pdev, &pdev->usb2_port,
					  base + offset);
	}

	if (!pdev->usb2_port.exist || !pdev->usb3_port.exist) {
		dev_err(pdev->dev, "Error: Only one port detected\n");
		return -ENODEV;
	}

	trace_cdnsp_init("Found USB 2.0 ports and  USB 3.0 ports.");

	pdev->usb2_port.regs = (struct cdnsp_port_regs __iomem *)
			       (&pdev->op_regs->port_reg_base + NUM_PORT_REGS *
				(pdev->usb2_port.port_num - 1));

	pdev->usb3_port.regs = (struct cdnsp_port_regs __iomem *)
			       (&pdev->op_regs->port_reg_base + NUM_PORT_REGS *
				(pdev->usb3_port.port_num - 1));

	return 0;
}

/*
 * Initialize memory for CDNSP (one-time init).
 *
 * Program the PAGESIZE register, initialize the device context array, create
 * device contexts, set up a command ring segment, create event
 * ring (one for now).
 */
int cdnsp_mem_init(struct cdnsp_device *pdev)
{
	struct device *dev = pdev->dev;
	int ret = -ENOMEM;
	unsigned int val;
	dma_addr_t dma;
	u32 page_size;
	u64 val_64;

	/*
	 * Use 4K pages, since that's common and the minimum the
	 * controller supports
	 */
	page_size = 1 << 12;

	val = readl(&pdev->op_regs->config_reg);
	val |= ((val & ~MAX_DEVS) | CDNSP_DEV_MAX_SLOTS) | CONFIG_U3E;
	writel(val, &pdev->op_regs->config_reg);

	/*
	 * Doorbell array must be physically contiguous
	 * and 64-byte (cache line) aligned.
	 */
	pdev->dcbaa = dma_alloc_coherent(dev, sizeof(*pdev->dcbaa),
					 &dma, GFP_KERNEL);
	if (!pdev->dcbaa)
		return -ENOMEM;

	pdev->dcbaa->dma = dma;

	cdnsp_write_64(dma, &pdev->op_regs->dcbaa_ptr);

	/*
	 * Initialize the ring segment pool.  The ring must be a contiguous
	 * structure comprised of TRBs. The TRBs must be 16 byte aligned,
	 * however, the command ring segment needs 64-byte aligned segments
	 * and our use of dma addresses in the trb_address_map radix tree needs
	 * TRB_SEGMENT_SIZE alignment, so driver pick the greater alignment
	 * need.
	 */
	pdev->segment_pool = dma_pool_create("CDNSP ring segments", dev,
					     TRB_SEGMENT_SIZE, TRB_SEGMENT_SIZE,
					     page_size);
	if (!pdev->segment_pool)
		goto release_dcbaa;

	pdev->device_pool = dma_pool_create("CDNSP input/output contexts", dev,
					    CDNSP_CTX_SIZE, 64, page_size);
	if (!pdev->device_pool)
		goto destroy_segment_pool;


	/* Set up the command ring to have one segments for now. */
	pdev->cmd_ring = cdnsp_ring_alloc(pdev, 1, TYPE_COMMAND, 0, GFP_KERNEL);
	if (!pdev->cmd_ring)
		goto destroy_device_pool;

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

	val = readl(&pdev->cap_regs->db_off);
	val &= DBOFF_MASK;
	pdev->dba = (void __iomem *)pdev->cap_regs + val;

	/* Set ir_set to interrupt register set 0 */
	pdev->ir_set = &pdev->run_regs->ir_set[0];

	/*
	 * Event ring setup: Allocate a normal ring, but also setup
	 * the event ring segment table (ERST).
	 */
	pdev->event_ring = cdnsp_ring_alloc(pdev, ERST_NUM_SEGS, TYPE_EVENT,
					    0, GFP_KERNEL);
	if (!pdev->event_ring)
		goto free_cmd_ring;

	ret = cdnsp_alloc_erst(pdev, pdev->event_ring, &pdev->erst);
	if (ret)
		goto free_event_ring;

	/* Set ERST count with the number of entries in the segment table. */
	val = readl(&pdev->ir_set->erst_size);
	val &= ERST_SIZE_MASK;
	val |= ERST_NUM_SEGS;
	writel(val, &pdev->ir_set->erst_size);

	/* Set the segment table base address. */
	val_64 = cdnsp_read_64(&pdev->ir_set->erst_base);
	val_64 &= ERST_PTR_MASK;
	val_64 |= (pdev->erst.erst_dma_addr & (u64)~ERST_PTR_MASK);
	cdnsp_write_64(val_64, &pdev->ir_set->erst_base);

	/* Set the event ring dequeue address. */
	cdnsp_set_event_deq(pdev);

	ret = cdnsp_setup_port_arrays(pdev);
	if (ret)
		goto free_erst;

	ret = cdnsp_alloc_priv_device(pdev);
	if (ret) {
		dev_err(pdev->dev,
			"Could not allocate cdnsp_device data structures\n");
		goto free_erst;
	}

	return 0;

free_erst:
	cdnsp_free_erst(pdev, &pdev->erst);
free_event_ring:
	cdnsp_ring_free(pdev, pdev->event_ring);
free_cmd_ring:
	cdnsp_ring_free(pdev, pdev->cmd_ring);
destroy_device_pool:
	dma_pool_destroy(pdev->device_pool);
destroy_segment_pool:
	dma_pool_destroy(pdev->segment_pool);
release_dcbaa:
	dma_free_coherent(dev, sizeof(*pdev->dcbaa), pdev->dcbaa,
			  pdev->dcbaa->dma);

	cdnsp_reset(pdev);

	return ret;
}
