Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Freescale QUICC Engine USB Host Controller Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (c) Freescale Semicondutor, Inc. 2006.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *               Shlomi Gridish <gridish@freescale.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *               Jerry Huang <Chang-Ming.Huang@freescale.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Copyright (c) Logic Product Development, Inc. 2007
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *               Peter Barada <peterb@logicpd.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * Copyright (c) MontaVista Software, Inc. 2008.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *               Anton Vorontsov <avorontsov@ru.mvista.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/usb/hcd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include "fhci.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define DUMMY_BD_BUFFER  0xdeadbeef
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define DUMMY2_BD_BUFFER 0xbaadf00d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) /* Transaction Descriptors bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define TD_R		0x8000 /* ready bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define TD_W		0x2000 /* wrap bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define TD_I		0x1000 /* interrupt on completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define TD_L		0x0800 /* last */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define TD_TC		0x0400 /* transmit CRC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define TD_CNF		0x0200 /* CNF - Must be always 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define TD_LSP		0x0100 /* Low-speed transaction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define TD_PID		0x00c0 /* packet id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define TD_RXER		0x0020 /* Rx error or not */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define TD_NAK		0x0010 /* No ack. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define TD_STAL		0x0008 /* Stall received */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define TD_TO		0x0004 /* time out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define TD_UN		0x0002 /* underrun */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define TD_NO		0x0010 /* Rx Non Octet Aligned Packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define TD_AB		0x0008 /* Frame Aborted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define TD_CR		0x0004 /* CRC Error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define TD_OV		0x0002 /* Overrun */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define TD_BOV		0x0001 /* Buffer Overrun */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define TD_ERRORS	(TD_NAK | TD_STAL | TD_TO | TD_UN | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 			 TD_NO | TD_AB | TD_CR | TD_OV | TD_BOV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define TD_PID_DATA0	0x0080 /* Data 0 toggle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define TD_PID_DATA1	0x00c0 /* Data 1 toggle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define TD_PID_TOGGLE	0x00c0 /* Data 0/1 toggle mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define TD_TOK_SETUP	0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #define TD_TOK_OUT	0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define TD_TOK_IN	0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define TD_ISO		0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define TD_ENDP		0x0780
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) #define TD_ADDR		0x007f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #define TD_ENDP_SHIFT 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) struct usb_td {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	__be16 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	__be16 length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	__be32 buf_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	__be16 extra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	__be16 reserved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) static struct usb_td __iomem *next_bd(struct usb_td __iomem *base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 				      struct usb_td __iomem *td,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 				      u16 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	if (status & TD_W)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		return base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		return ++td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) void fhci_push_dummy_bd(struct endpoint *ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	if (!ep->already_pushed_dummy_bd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		u16 td_status = in_be16(&ep->empty_td->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		out_be32(&ep->empty_td->buf_ptr, DUMMY_BD_BUFFER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		/* get the next TD in the ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		ep->empty_td = next_bd(ep->td_base, ep->empty_td, td_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		ep->already_pushed_dummy_bd = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) /* destroy an USB endpoint */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) void fhci_ep0_free(struct fhci_usb *usb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	struct endpoint *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	ep = usb->ep0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	if (ep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		if (ep->td_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 			cpm_muram_free(cpm_muram_offset(ep->td_base));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		if (kfifo_initialized(&ep->conf_frame_Q)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 			size = cq_howmany(&ep->conf_frame_Q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 			for (; size; size--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 				struct packet *pkt = cq_get(&ep->conf_frame_Q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 				kfree(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 			cq_delete(&ep->conf_frame_Q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		if (kfifo_initialized(&ep->empty_frame_Q)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 			size = cq_howmany(&ep->empty_frame_Q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 			for (; size; size--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 				struct packet *pkt = cq_get(&ep->empty_frame_Q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 				kfree(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 			cq_delete(&ep->empty_frame_Q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		if (kfifo_initialized(&ep->dummy_packets_Q)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 			size = cq_howmany(&ep->dummy_packets_Q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 			for (; size; size--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 				u8 *buff = cq_get(&ep->dummy_packets_Q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 				kfree(buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 			cq_delete(&ep->dummy_packets_Q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		kfree(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		usb->ep0 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  * create the endpoint structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  * arguments:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)  * usb		A pointer to the data structure of the USB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)  * data_mem	The data memory partition(BUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)  * ring_len	TD ring length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) u32 fhci_create_ep(struct fhci_usb *usb, enum fhci_mem_alloc data_mem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 			   u32 ring_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	struct endpoint *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	struct usb_td __iomem *td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	unsigned long ep_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	char *err_for = "endpoint PRAM";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	int ep_mem_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	/* we need at least 3 TDs in the ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	if (!(ring_len > 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		fhci_err(usb->fhci, "illegal TD ring length parameters\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	ep = kzalloc(sizeof(*ep), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	if (!ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	ep_mem_size = ring_len * sizeof(*td) + sizeof(struct fhci_ep_pram);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	ep_offset = cpm_muram_alloc(ep_mem_size, 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	if (IS_ERR_VALUE(ep_offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	ep->td_base = cpm_muram_addr(ep_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	/* zero all queue pointers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	if (cq_new(&ep->conf_frame_Q, ring_len + 2) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	    cq_new(&ep->empty_frame_Q, ring_len + 2) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	    cq_new(&ep->dummy_packets_Q, ring_len + 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		err_for = "frame_queues";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	for (i = 0; i < (ring_len + 1); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		struct packet *pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		u8 *buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		pkt = kmalloc(sizeof(*pkt), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		if (!pkt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 			err_for = "frame";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 			goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		buff = kmalloc_array(1028, sizeof(*buff), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		if (!buff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 			kfree(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 			err_for = "buffer";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 			goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		cq_put(&ep->empty_frame_Q, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		cq_put(&ep->dummy_packets_Q, buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	/* we put the endpoint parameter RAM right behind the TD ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	ep->ep_pram_ptr = (void __iomem *)ep->td_base + sizeof(*td) * ring_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	ep->conf_td = ep->td_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	ep->empty_td = ep->td_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	ep->already_pushed_dummy_bd = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	/* initialize tds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	td = ep->td_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	for (i = 0; i < ring_len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		out_be32(&td->buf_ptr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		out_be16(&td->status, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		out_be16(&td->length, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		out_be16(&td->extra, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		td++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	td--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	out_be16(&td->status, TD_W); /* for last TD set Wrap bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	out_be16(&td->length, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	/* endpoint structure has been created */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	usb->ep0 = ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	fhci_ep0_free(usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	kfree(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	fhci_err(usb->fhci, "no memory for the %s\n", err_for);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)  * initialize the endpoint register according to the given parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)  * artuments:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)  * usb		A pointer to the data strucutre of the USB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)  * ep		A pointer to the endpoint structre
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)  * data_mem	The data memory partition(BUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) void fhci_init_ep_registers(struct fhci_usb *usb, struct endpoint *ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 			    enum fhci_mem_alloc data_mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	u8 rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	/* set the endpoint registers according to the endpoint */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	out_be16(&usb->fhci->regs->usb_usep[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		 USB_TRANS_CTR | USB_EP_MF | USB_EP_RTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	out_be16(&usb->fhci->pram->ep_ptr[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		 cpm_muram_offset(ep->ep_pram_ptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	rt = (BUS_MODE_BO_BE | BUS_MODE_GBL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) #ifdef MULTI_DATA_BUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	if (data_mem == MEM_SECONDARY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		rt |= BUS_MODE_DTB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	out_8(&ep->ep_pram_ptr->rx_func_code, rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	out_8(&ep->ep_pram_ptr->tx_func_code, rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	out_be16(&ep->ep_pram_ptr->rx_buff_len, 1028);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	out_be16(&ep->ep_pram_ptr->rx_base, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	out_be16(&ep->ep_pram_ptr->tx_base, cpm_muram_offset(ep->td_base));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	out_be16(&ep->ep_pram_ptr->rx_bd_ptr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	out_be16(&ep->ep_pram_ptr->tx_bd_ptr, cpm_muram_offset(ep->td_base));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	out_be32(&ep->ep_pram_ptr->tx_state, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)  * Collect the submitted frames and inform the application about them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)  * It is also preparing the TDs for new frames. If the Tx interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)  * are disabled, the application should call that routine to get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)  * confirmation about the submitted frames. Otherwise, the routine is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)  * called from the interrupt service routine during the Tx interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)  * In that case the application is informed by calling the application
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)  * specific 'fhci_transaction_confirm' routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) static void fhci_td_transaction_confirm(struct fhci_usb *usb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	struct endpoint *ep = usb->ep0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	struct packet *pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	struct usb_td __iomem *td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	u16 extra_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	u16 td_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	u16 td_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	u32 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	 * collect transmitted BDs from the chip. The routine clears all BDs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	 * with R bit = 0 and the pointer to data buffer is not NULL, that is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	 * BDs which point to the transmitted data buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		td = ep->conf_td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		td_status = in_be16(&td->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		td_length = in_be16(&td->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		buf = in_be32(&td->buf_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		extra_data = in_be16(&td->extra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		/* check if the TD is empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		if (!(!(td_status & TD_R) && ((td_status & ~TD_W) || buf)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		/* check if it is a dummy buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		else if ((buf == DUMMY_BD_BUFFER) && !(td_status & ~TD_W))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		/* mark TD as empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		clrbits16(&td->status, ~TD_W);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		out_be16(&td->length, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 		out_be32(&td->buf_ptr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		out_be16(&td->extra, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		/* advance the TD pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		ep->conf_td = next_bd(ep->td_base, ep->conf_td, td_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		/* check if it is a dummy buffer(type2) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		if ((buf == DUMMY2_BD_BUFFER) && !(td_status & ~TD_W))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		pkt = cq_get(&ep->conf_frame_Q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		if (!pkt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 			fhci_err(usb->fhci, "no frame to confirm\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		if (td_status & TD_ERRORS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 			if (td_status & TD_RXER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 				if (td_status & TD_CR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 					pkt->status = USB_TD_RX_ER_CRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 				else if (td_status & TD_AB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 					pkt->status = USB_TD_RX_ER_BITSTUFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 				else if (td_status & TD_OV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 					pkt->status = USB_TD_RX_ER_OVERUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 				else if (td_status & TD_BOV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 					pkt->status = USB_TD_RX_DATA_OVERUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 				else if (td_status & TD_NO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 					pkt->status = USB_TD_RX_ER_NONOCT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 					fhci_err(usb->fhci, "illegal error "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 						 "occurred\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 			} else if (td_status & TD_NAK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 				pkt->status = USB_TD_TX_ER_NAK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 			else if (td_status & TD_TO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 				pkt->status = USB_TD_TX_ER_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 			else if (td_status & TD_UN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 				pkt->status = USB_TD_TX_ER_UNDERUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 			else if (td_status & TD_STAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 				pkt->status = USB_TD_TX_ER_STALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 				fhci_err(usb->fhci, "illegal error occurred\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		} else if ((extra_data & TD_TOK_IN) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 				pkt->len > td_length - CRC_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 			pkt->status = USB_TD_RX_DATA_UNDERUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		if (extra_data & TD_TOK_IN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 			pkt->len = td_length - CRC_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		else if (pkt->info & PKT_ZLP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 			pkt->len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 			pkt->len = td_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		fhci_transaction_confirm(usb, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)  * Submitting a data frame to a specified endpoint of a USB device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)  * The frame is put in the driver's transmit queue for this endpoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)  * Arguments:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)  * usb          A pointer to the USB structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)  * pkt          A pointer to the user frame structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)  * trans_type   Transaction tyep - IN,OUT or SETUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)  * dest_addr    Device address - 0~127
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)  * dest_ep      Endpoint number of the device - 0~16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)  * trans_mode   Pipe type - ISO,Interrupt,bulk or control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)  * dest_speed   USB speed - Low speed or FULL speed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)  * data_toggle  Data sequence toggle - 0 or 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) u32 fhci_host_transaction(struct fhci_usb *usb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 			  struct packet *pkt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 			  enum fhci_ta_type trans_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 			  u8 dest_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 			  u8 dest_ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 			  enum fhci_tf_mode trans_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 			  enum fhci_speed dest_speed, u8 data_toggle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	struct endpoint *ep = usb->ep0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	struct usb_td __iomem *td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	u16 extra_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	u16 td_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	fhci_usb_disable_interrupt(usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	/* start from the next BD that should be filled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	td = ep->empty_td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	td_status = in_be16(&td->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	if (td_status & TD_R && in_be16(&td->length)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 		/* if the TD is not free */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		fhci_usb_enable_interrupt(usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	/* get the next TD in the ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	ep->empty_td = next_bd(ep->td_base, ep->empty_td, td_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	fhci_usb_enable_interrupt(usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	pkt->priv_data = td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	out_be32(&td->buf_ptr, virt_to_phys(pkt->data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	/* sets up transaction parameters - addr,endp,dir,and type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	extra_data = (dest_ep << TD_ENDP_SHIFT) | dest_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	switch (trans_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	case FHCI_TA_IN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		extra_data |= TD_TOK_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	case FHCI_TA_OUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		extra_data |= TD_TOK_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	case FHCI_TA_SETUP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		extra_data |= TD_TOK_SETUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	if (trans_mode == FHCI_TF_ISO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 		extra_data |= TD_ISO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	out_be16(&td->extra, extra_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	/* sets up the buffer descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	td_status = ((td_status & TD_W) | TD_R | TD_L | TD_I | TD_CNF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	if (!(pkt->info & PKT_NO_CRC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		td_status |= TD_TC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	switch (trans_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	case FHCI_TA_IN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		if (data_toggle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 			pkt->info |= PKT_PID_DATA1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 			pkt->info |= PKT_PID_DATA0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		if (data_toggle) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 			td_status |= TD_PID_DATA1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 			pkt->info |= PKT_PID_DATA1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 			td_status |= TD_PID_DATA0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 			pkt->info |= PKT_PID_DATA0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	if ((dest_speed == FHCI_LOW_SPEED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	    (usb->port_status == FHCI_PORT_FULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 		td_status |= TD_LSP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	out_be16(&td->status, td_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	/* set up buffer length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	if (trans_type == FHCI_TA_IN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		out_be16(&td->length, pkt->len + CRC_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 		out_be16(&td->length, pkt->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	/* put the frame to the confirmation queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	cq_put(&ep->conf_frame_Q, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	if (cq_howmany(&ep->conf_frame_Q) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		out_8(&usb->fhci->regs->usb_uscom, USB_CMD_STR_FIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) /* Reset the Tx BD ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) void fhci_flush_bds(struct fhci_usb *usb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	u16 td_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	struct usb_td __iomem *td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	struct endpoint *ep = usb->ep0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	td = ep->td_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 		td_status = in_be16(&td->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 		in_be32(&td->buf_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		in_be16(&td->extra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		/* if the TD is not empty - we'll confirm it as Timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 		if (td_status & TD_R)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 			out_be16(&td->status, (td_status & ~TD_R) | TD_TO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		/* if this TD is dummy - let's skip this TD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 		else if (in_be32(&td->buf_ptr) == DUMMY_BD_BUFFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 			out_be32(&td->buf_ptr, DUMMY2_BD_BUFFER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 		/* if this is the last TD - break */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 		if (td_status & TD_W)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		td++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	fhci_td_transaction_confirm(usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	td = ep->td_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 		out_be16(&td->status, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 		out_be16(&td->length, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 		out_be32(&td->buf_ptr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		out_be16(&td->extra, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 		td++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	} while (!(in_be16(&td->status) & TD_W));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	out_be16(&td->status, TD_W); /* for last TD set Wrap bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	out_be16(&td->length, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	out_be32(&td->buf_ptr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	out_be16(&td->extra, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	out_be16(&ep->ep_pram_ptr->tx_bd_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 		 in_be16(&ep->ep_pram_ptr->tx_base));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	out_be32(&ep->ep_pram_ptr->tx_state, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	out_be16(&ep->ep_pram_ptr->tx_cnt, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	ep->empty_td = ep->td_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	ep->conf_td = ep->td_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)  * Flush all transmitted packets from TDs in the actual frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)  * This routine is called when something wrong with the controller and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)  * we want to get rid of the actual frame and start again next frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) void fhci_flush_actual_frame(struct fhci_usb *usb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	u8 mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	u16 tb_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	u16 td_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	u32 buf_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	struct usb_td __iomem *td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	struct endpoint *ep = usb->ep0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	/* disable the USB controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	mode = in_8(&usb->fhci->regs->usb_usmod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	out_8(&usb->fhci->regs->usb_usmod, mode & ~USB_MODE_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	tb_ptr = in_be16(&ep->ep_pram_ptr->tx_bd_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	td = cpm_muram_addr(tb_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	td_status = in_be16(&td->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	buf_ptr = in_be32(&td->buf_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	in_be16(&td->extra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 		if (td_status & TD_R) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 			out_be16(&td->status, (td_status & ~TD_R) | TD_TO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 			out_be32(&td->buf_ptr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 			ep->already_pushed_dummy_bd = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		/* advance the TD pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 		td = next_bd(ep->td_base, td, td_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		td_status = in_be16(&td->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 		buf_ptr = in_be32(&td->buf_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 		in_be16(&td->extra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	} while ((td_status & TD_R) || buf_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	fhci_td_transaction_confirm(usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	out_be16(&ep->ep_pram_ptr->tx_bd_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 		 in_be16(&ep->ep_pram_ptr->tx_base));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	out_be32(&ep->ep_pram_ptr->tx_state, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	out_be16(&ep->ep_pram_ptr->tx_cnt, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	ep->empty_td = ep->td_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	ep->conf_td = ep->td_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	usb->actual_frame->frame_status = FRAME_TIMER_END_TRANSMISSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	/* reset the event register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	out_be16(&usb->fhci->regs->usb_usber, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	/* enable the USB controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	out_8(&usb->fhci->regs->usb_usmod, mode | USB_MODE_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) /* handles Tx confirm and Tx error interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) void fhci_tx_conf_interrupt(struct fhci_usb *usb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	fhci_td_transaction_confirm(usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	 * Schedule another transaction to this frame only if we have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	 * already confirmed all transaction in the frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	if (((fhci_get_sof_timer_count(usb) < usb->max_frame_usage) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	     (usb->actual_frame->frame_status & FRAME_END_TRANSMISSION)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	    (list_empty(&usb->actual_frame->tds_list)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 		fhci_schedule_transactions(usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) void fhci_host_transmit_actual_frame(struct fhci_usb *usb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	u16 tb_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	u16 td_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	struct usb_td __iomem *td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	struct endpoint *ep = usb->ep0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	tb_ptr = in_be16(&ep->ep_pram_ptr->tx_bd_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	td = cpm_muram_addr(tb_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	if (in_be32(&td->buf_ptr) == DUMMY_BD_BUFFER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 		struct usb_td __iomem *old_td = td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 		ep->already_pushed_dummy_bd = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 		td_status = in_be16(&td->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 		/* gets the next TD in the ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 		td = next_bd(ep->td_base, td, td_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 		tb_ptr = cpm_muram_offset(td);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 		out_be16(&ep->ep_pram_ptr->tx_bd_ptr, tb_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 		/* start transmit only if we have something in the TDs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 		if (in_be16(&td->status) & TD_R)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 			out_8(&usb->fhci->regs->usb_uscom, USB_CMD_STR_FIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 		if (in_be32(&ep->conf_td->buf_ptr) == DUMMY_BD_BUFFER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 			out_be32(&old_td->buf_ptr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 			ep->conf_td = next_bd(ep->td_base, ep->conf_td,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 					      td_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 			out_be32(&old_td->buf_ptr, DUMMY2_BD_BUFFER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }