1/* ==========================================================================
2 * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd_intr.c $
3 * $Revision: 1.2 $
4 * $Date: 2008-11-21 05:39:15 $
5 * $Change: 1115682 $
6 *
7 * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
8 * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
9 * otherwise expressly agreed to in writing between Synopsys and you.
10 *
11 * The Software IS NOT an item of Licensed Software or Licensed Product under
12 * any End User Software License Agreement or Agreement for Licensed Product
13 * with Synopsys or any supplement thereto. You are permitted to use and
14 * redistribute this Software in source and binary forms, with or without
15 * modification, provided that redistributions of source code must retain this
16 * notice. You may not view, use, disclose, copy or distribute this file or
17 * any information contained herein except pursuant to this license grant from
18 * Synopsys. If you do not agree with this notice, including the disclaimer
19 * below, then you are not authorized to use the Software.
20 *
21 * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 * DAMAGE.
32 * ========================================================================== */
33#ifndef DWC_HOST_ONLY
34#include <linux/interrupt.h>
35#include <linux/dma-mapping.h>
36#include <linux/version.h>
37
38#include "dwc_otg_driver.h"
39#include "dwc_otg_pcd.h"
40
41
42#define DEBUG_EP0
43
44/* request functions defined in "dwc_otg_pcd.c" */
45
46/** @file
47 * This file contains the implementation of the PCD Interrupt handlers.
48 *
49 * The PCD handles the device interrupts.  Many conditions can cause a
50 * device interrupt. When an interrupt occurs, the device interrupt
51 * service routine determines the cause of the interrupt and
52 * dispatches handling to the appropriate function. These interrupt
53 * handling functions are described below.
54 * All interrupt registers are processed from LSB to MSB.
55 */
56
57
58/**
59 * This function prints the ep0 state for debug purposes.
60 */
61static inline void print_ep0_state(dwc_otg_pcd_t *pcd)
62{
63#ifdef DEBUG
64	char str[40];
65
66	switch (pcd->ep0state) {
67	case EP0_DISCONNECT:
68		strcpy(str, "EP0_DISCONNECT");
69		break;
70	case EP0_IDLE:
71		strcpy(str, "EP0_IDLE");
72		break;
73	case EP0_IN_DATA_PHASE:
74		strcpy(str, "EP0_IN_DATA_PHASE");
75		break;
76	case EP0_OUT_DATA_PHASE:
77		strcpy(str, "EP0_OUT_DATA_PHASE");
78		break;
79	case EP0_IN_STATUS_PHASE:
80		strcpy(str,"EP0_IN_STATUS_PHASE");
81		break;
82	case EP0_OUT_STATUS_PHASE:
83		strcpy(str,"EP0_OUT_STATUS_PHASE");
84		break;
85	case EP0_STALL:
86		strcpy(str,"EP0_STALL");
87		break;
88	default:
89		strcpy(str,"EP0_INVALID");
90	}
91
92	DWC_DEBUGPL(DBG_ANY, "%s(%d)\n", str, pcd->ep0state);
93#endif
94}
95
96/**
97 * This function returns pointer to in ep struct with number ep_num
98 */
99static inline dwc_otg_pcd_ep_t* get_in_ep(dwc_otg_pcd_t *pcd, uint32_t ep_num)
100{
101	int i;
102	int num_in_eps = GET_CORE_IF(pcd)->dev_if->num_in_eps;
103	if(ep_num == 0) {
104		return &pcd->ep0;
105	}
106	else {
107		for(i = 0; i < num_in_eps; ++i)
108		{
109			if(pcd->in_ep[i].dwc_ep.num == ep_num)
110				return &pcd->in_ep[i];
111		}
112		return 0;
113	}
114}
115/**
116 * This function returns pointer to out ep struct with number ep_num
117 */
118static inline dwc_otg_pcd_ep_t* get_out_ep(dwc_otg_pcd_t *pcd, uint32_t ep_num)
119{
120	int i;
121	int num_out_eps = GET_CORE_IF(pcd)->dev_if->num_out_eps;
122	if(ep_num == 0) {
123		return &pcd->ep0;
124	}
125	else {
126		for(i = 0; i < num_out_eps; ++i)
127		{
128			if(pcd->out_ep[i].dwc_ep.num == ep_num)
129				return &pcd->out_ep[i];
130		}
131		return 0;
132	}
133}
134/**
135 * This functions gets a pointer to an EP from the wIndex address
136 * value of the control request.
137 */
138static dwc_otg_pcd_ep_t *get_ep_by_addr (dwc_otg_pcd_t *pcd, u16 wIndex)
139{
140	dwc_otg_pcd_ep_t	*ep;
141
142	if ((wIndex & USB_ENDPOINT_NUMBER_MASK) == 0)
143		return &pcd->ep0;
144	list_for_each_entry(ep, &pcd->gadget.ep_list, ep.ep_list)
145	{
146		u8	bEndpointAddress;
147
148		if (!ep->desc)
149			continue;
150
151		bEndpointAddress = ep->desc->bEndpointAddress;
152		if((wIndex & (USB_DIR_IN | USB_ENDPOINT_NUMBER_MASK))
153			== (bEndpointAddress & (USB_DIR_IN | USB_ENDPOINT_NUMBER_MASK)))
154			return ep;
155	}
156	return NULL;
157}
158
159/**
160 * This function checks the EP request queue, if the queue is not
161 * empty the next request is started.
162 */
163void start_next_request(dwc_otg_pcd_ep_t *ep)
164{
165	dwc_otg_pcd_request_t *req = 0;
166	uint32_t max_transfer = GET_CORE_IF(ep->pcd)->core_params->max_transfer_size;
167
168	if (!list_empty(&ep->queue)) {
169		req = list_entry(ep->queue.next,
170			   dwc_otg_pcd_request_t, queue);
171
172		/* Setup and start the Transfer */
173		ep->dwc_ep.dma_addr = req->req.dma;
174		ep->dwc_ep.start_xfer_buff = req->req.buf;
175		ep->dwc_ep.xfer_buff = req->req.buf;
176		ep->dwc_ep.sent_zlp = 0;
177		ep->dwc_ep.total_len = req->req.length;
178		ep->dwc_ep.xfer_len = 0;
179		ep->dwc_ep.xfer_count = 0;
180
181		if(max_transfer > MAX_TRANSFER_SIZE) {
182			ep->dwc_ep.maxxfer = max_transfer - (max_transfer % ep->dwc_ep.maxpacket);
183		} else {
184			ep->dwc_ep.maxxfer = max_transfer;
185		}
186
187		if(req->req.zero) {
188			if((ep->dwc_ep.total_len % ep->dwc_ep.maxpacket == 0)
189					&& (ep->dwc_ep.total_len != 0)) {
190				ep->dwc_ep.sent_zlp = 1;
191			}
192
193		}
194
195		dwc_otg_ep_start_transfer(GET_CORE_IF(ep->pcd), &ep->dwc_ep);
196	}
197}
198
199/**
200 * This function handles the SOF Interrupts. At this time the SOF
201 * Interrupt is disabled.
202 */
203int32_t dwc_otg_pcd_handle_sof_intr(dwc_otg_pcd_t *pcd)
204{
205	dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
206
207	gintsts_data_t gintsts;
208
209	DWC_DEBUGPL(DBG_PCD, "SOF\n");
210
211	/* Clear interrupt */
212	gintsts.d32 = 0;
213	gintsts.b.sofintr = 1;
214	dwc_write_reg32 (&core_if->core_global_regs->gintsts, gintsts.d32);
215
216	return 1;
217}
218
219
220/**
221 * This function handles the Rx Status Queue Level Interrupt, which
222 * indicates that there is a least one packet in the Rx FIFO.  The
223 * packets are moved from the FIFO to memory, where they will be
224 * processed when the Endpoint Interrupt Register indicates Transfer
225 * Complete or SETUP Phase Done.
226 *
227 * Repeat the following until the Rx Status Queue is empty:
228 *	 -# Read the Receive Status Pop Register (GRXSTSP) to get Packet
229 *		info
230 *	 -# If Receive FIFO is empty then skip to step Clear the interrupt
231 *		and exit
232 *	 -# If SETUP Packet call dwc_otg_read_setup_packet to copy the
233 *		SETUP data to the buffer
234 *	 -# If OUT Data Packet call dwc_otg_read_packet to copy the data
235 *		to the destination buffer
236 */
237int32_t dwc_otg_pcd_handle_rx_status_q_level_intr(dwc_otg_pcd_t *pcd)
238{
239	dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
240	dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
241	gintmsk_data_t gintmask = {.d32=0};
242	device_grxsts_data_t status;
243	dwc_otg_pcd_ep_t *ep;
244	gintsts_data_t gintsts;
245#ifdef DEBUG
246	static char *dpid_str[] ={ "D0", "D2", "D1", "MDATA" };
247#endif
248
249	//DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _pcd);
250	/* Disable the Rx Status Queue Level interrupt */
251	gintmask.b.rxstsqlvl= 1;
252	dwc_modify_reg32(&global_regs->gintmsk, gintmask.d32, 0);
253
254	/* Get the Status from the top of the FIFO */
255	status.d32 = dwc_read_reg32(&global_regs->grxstsp);
256
257	DWC_DEBUGPL(DBG_PCD, "EP:%d BCnt:%d DPID:%s "
258					"pktsts:%x Frame:%d(0x%0x)\n",
259					status.b.epnum, status.b.bcnt,
260					dpid_str[status.b.dpid],
261					status.b.pktsts, status.b.fn, status.b.fn);
262	/* Get pointer to EP structure */
263	ep = get_out_ep(pcd, status.b.epnum);
264
265	switch (status.b.pktsts) {
266	case DWC_DSTS_GOUT_NAK:
267		DWC_DEBUGPL(DBG_PCDV, "Global OUT NAK\n");
268		break;
269	case DWC_STS_DATA_UPDT:
270		DWC_DEBUGPL(DBG_PCDV, "OUT Data Packet\n");
271		if (status.b.bcnt && ep->dwc_ep.xfer_buff) {
272			/** @todo NGS Check for buffer overflow? */
273			dwc_otg_read_packet(core_if,
274						 ep->dwc_ep.xfer_buff,
275						 status.b.bcnt);
276			ep->dwc_ep.xfer_count += status.b.bcnt;
277			ep->dwc_ep.xfer_buff += status.b.bcnt;
278		}
279		break;
280	case DWC_STS_XFER_COMP:
281		DWC_DEBUGPL(DBG_PCDV, "OUT Complete\n");
282		break;
283	case DWC_DSTS_SETUP_COMP:
284#ifdef DEBUG_EP0
285		DWC_DEBUGPL(DBG_PCDV, "Setup Complete\n");
286#endif
287		break;
288case DWC_DSTS_SETUP_UPDT:
289		dwc_otg_read_setup_packet(core_if, pcd->setup_pkt->d32);
290#ifdef DEBUG_EP0
291		DWC_DEBUGPL(DBG_PCD,
292				"SETUP PKT: %02x.%02x v%04x i%04x l%04x\n",
293				pcd->setup_pkt->req.bRequestType,
294				pcd->setup_pkt->req.bRequest,
295				pcd->setup_pkt->req.wValue,
296				pcd->setup_pkt->req.wIndex,
297				pcd->setup_pkt->req.wLength);
298#endif
299		ep->dwc_ep.xfer_count += status.b.bcnt;
300		break;
301	default:
302		DWC_DEBUGPL(DBG_PCDV, "Invalid Packet Status (0x%0x)\n",
303				status.b.pktsts);
304		break;
305	}
306
307	/* Enable the Rx Status Queue Level interrupt */
308	dwc_modify_reg32(&global_regs->gintmsk, 0, gintmask.d32);
309	/* Clear interrupt */
310	gintsts.d32 = 0;
311	gintsts.b.rxstsqlvl = 1;
312	dwc_write_reg32 (&global_regs->gintsts, gintsts.d32);
313
314	//DWC_DEBUGPL(DBG_PCDV, "EXIT: %s\n", __func__);
315	return 1;
316}
317/**
318 * This function examines the Device IN Token Learning Queue to
319 * determine the EP number of the last IN token received.  This
320 * implementation is for the Mass Storage device where there are only
321 * 2 IN EPs (Control-IN and BULK-IN).
322 *
323 * The EP numbers for the first six IN Tokens are in DTKNQR1 and there
324 * are 8 EP Numbers in each of the other possible DTKNQ Registers.
325 *
326 * @param core_if Programming view of DWC_otg controller.
327 *
328 */
329static inline int get_ep_of_last_in_token(dwc_otg_core_if_t *core_if)
330{
331	dwc_otg_device_global_regs_t *dev_global_regs =
332			core_if->dev_if->dev_global_regs;
333	const uint32_t TOKEN_Q_DEPTH = core_if->hwcfg2.b.dev_token_q_depth;
334	/* Number of Token Queue Registers */
335	const int DTKNQ_REG_CNT = (TOKEN_Q_DEPTH + 7) / 8;
336	dtknq1_data_t dtknqr1;
337	uint32_t in_tkn_epnums[4];
338	int ndx = 0;
339	int i = 0;
340	volatile uint32_t *addr = &dev_global_regs->dtknqr1;
341	int epnum = 0;
342
343	//DWC_DEBUGPL(DBG_PCD,"dev_token_q_depth=%d\n",TOKEN_Q_DEPTH);
344
345
346	/* Read the DTKNQ Registers */
347	for (i = 0; i < DTKNQ_REG_CNT; i++)
348	{
349		in_tkn_epnums[ i ] = dwc_read_reg32(addr);
350		DWC_DEBUGPL(DBG_PCDV, "DTKNQR%d=0x%08x\n", i+1,
351				in_tkn_epnums[i]);
352		if (addr == &dev_global_regs->dvbusdis) {
353			addr = &dev_global_regs->dtknqr3_dthrctl;
354		}
355		else {
356			++addr;
357		}
358
359	}
360
361	/* Copy the DTKNQR1 data to the bit field. */
362	dtknqr1.d32 = in_tkn_epnums[0];
363	/* Get the EP numbers */
364	in_tkn_epnums[0] = dtknqr1.b.epnums0_5;
365	ndx = dtknqr1.b.intknwptr - 1;
366
367	//DWC_DEBUGPL(DBG_PCDV,"ndx=%d\n",ndx);
368	if (ndx == -1) {
369		/** @todo Find a simpler way to calculate the max
370		 * queue position.*/
371		int cnt = TOKEN_Q_DEPTH;
372		if (TOKEN_Q_DEPTH <= 6) {
373			cnt = TOKEN_Q_DEPTH - 1;
374		}
375		else if (TOKEN_Q_DEPTH <= 14) {
376			cnt = TOKEN_Q_DEPTH - 7;
377		}
378		else if (TOKEN_Q_DEPTH <= 22) {
379			cnt = TOKEN_Q_DEPTH - 15;
380		}
381		else {
382			cnt = TOKEN_Q_DEPTH - 23;
383		}
384		epnum = (in_tkn_epnums[ DTKNQ_REG_CNT - 1 ] >> (cnt * 4)) & 0xF;
385	}
386	else {
387		if (ndx <= 5) {
388			epnum = (in_tkn_epnums[0] >> (ndx * 4)) & 0xF;
389		}
390		else if (ndx <= 13) {
391			ndx -= 6;
392			epnum = (in_tkn_epnums[1] >> (ndx * 4)) & 0xF;
393		}
394		else if (ndx <= 21) {
395			ndx -= 14;
396			epnum = (in_tkn_epnums[2] >> (ndx * 4)) & 0xF;
397		}
398		else if (ndx <= 29) {
399			ndx -= 22;
400			epnum = (in_tkn_epnums[3] >> (ndx * 4)) & 0xF;
401		}
402	}
403	//DWC_DEBUGPL(DBG_PCD,"epnum=%d\n",epnum);
404	return epnum;
405}
406
407/**
408 * This interrupt occurs when the non-periodic Tx FIFO is half-empty.
409 * The active request is checked for the next packet to be loaded into
410 * the non-periodic Tx FIFO.
411 */
412int32_t dwc_otg_pcd_handle_np_tx_fifo_empty_intr(dwc_otg_pcd_t *pcd)
413{
414	dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
415	dwc_otg_core_global_regs_t *global_regs =
416			core_if->core_global_regs;
417	dwc_otg_dev_in_ep_regs_t *ep_regs;
418	gnptxsts_data_t txstatus = {.d32 = 0};
419	gintsts_data_t gintsts;
420
421	int epnum = 0;
422	dwc_otg_pcd_ep_t *ep = 0;
423	uint32_t len = 0;
424	int dwords;
425
426	/* Get the epnum from the IN Token Learning Queue. */
427	epnum = get_ep_of_last_in_token(core_if);
428	ep = get_in_ep(pcd, epnum);
429
430	DWC_DEBUGPL(DBG_PCD, "NP TxFifo Empty: %s(%d) \n", ep->ep.name, epnum);
431	ep_regs = core_if->dev_if->in_ep_regs[epnum];
432
433	len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
434	if (len > ep->dwc_ep.maxpacket) {
435		len = ep->dwc_ep.maxpacket;
436	}
437	dwords = (len + 3)/4;
438
439
440	/* While there is space in the queue and space in the FIFO and
441	* More data to tranfer, Write packets to the Tx FIFO */
442	txstatus.d32 = dwc_read_reg32(&global_regs->gnptxsts);
443	DWC_DEBUGPL(DBG_PCDV, "b4 GNPTXSTS=0x%08x\n",txstatus.d32);
444
445	while  (txstatus.b.nptxqspcavail > 0 &&
446		txstatus.b.nptxfspcavail > dwords &&
447		ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len) {
448		/* Write the FIFO */
449		dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0);
450		len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
451
452		if (len > ep->dwc_ep.maxpacket) {
453			len = ep->dwc_ep.maxpacket;
454		}
455
456		dwords = (len + 3)/4;
457		txstatus.d32 = dwc_read_reg32(&global_regs->gnptxsts);
458		DWC_DEBUGPL(DBG_PCDV,"GNPTXSTS=0x%08x\n",txstatus.d32);
459	}
460
461	DWC_DEBUGPL(DBG_PCDV, "GNPTXSTS=0x%08x\n",
462			dwc_read_reg32(&global_regs->gnptxsts));
463
464	/* Clear interrupt */
465	gintsts.d32 = 0;
466	gintsts.b.nptxfempty = 1;
467	dwc_write_reg32 (&global_regs->gintsts, gintsts.d32);
468
469	return 1;
470}
471
472/**
473 * This function is called when dedicated Tx FIFO Empty interrupt occurs.
474 * The active request is checked for the next packet to be loaded into
475 * apropriate Tx FIFO.
476 */
477static int32_t write_empty_tx_fifo(dwc_otg_pcd_t *pcd, uint32_t epnum)
478{
479	dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
480	dwc_otg_dev_if_t* dev_if = core_if->dev_if;
481	dwc_otg_dev_in_ep_regs_t *ep_regs;
482	dtxfsts_data_t txstatus = {.d32 = 0};
483	dwc_otg_pcd_ep_t *ep = 0;
484	uint32_t len = 0;
485	int dwords;
486
487	ep = get_in_ep(pcd, epnum);
488
489	DWC_DEBUGPL(DBG_PCD, "Dedicated TxFifo Empty: %s(%d) \n", ep->ep.name, epnum);
490
491	ep_regs = core_if->dev_if->in_ep_regs[epnum];
492
493	len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
494
495	if (len > ep->dwc_ep.maxpacket) {
496		len = ep->dwc_ep.maxpacket;
497	}
498
499	dwords = (len + 3)/4;
500
501	/* While there is space in the queue and space in the FIFO and
502	 * More data to tranfer, Write packets to the Tx FIFO */
503	txstatus.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dtxfsts);
504	DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n",epnum,txstatus.d32);
505
506	while  (txstatus.b.txfspcavail > dwords &&
507		ep->dwc_ep.xfer_count < ep->dwc_ep.xfer_len &&
508		ep->dwc_ep.xfer_len != 0) {
509		/* Write the FIFO */
510		dwc_otg_ep_write_packet(core_if, &ep->dwc_ep, 0);
511
512		len = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
513		if (len > ep->dwc_ep.maxpacket) {
514			len = ep->dwc_ep.maxpacket;
515		}
516
517		dwords = (len + 3)/4;
518		txstatus.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dtxfsts);
519		DWC_DEBUGPL(DBG_PCDV,"dtxfsts[%d]=0x%08x\n", epnum, txstatus.d32);
520	}
521
522	DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n",epnum,dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dtxfsts));
523
524	return 1;
525}
526
527
528/**
529 * This function is called when the Device is disconnected. It stops
530 * any active requests and informs the Gadget driver of the
531 * disconnect.
532 */
533void dwc_otg_pcd_stop(dwc_otg_pcd_t *pcd)
534{
535	int i, num_in_eps, num_out_eps;
536	dwc_otg_pcd_ep_t *ep;
537
538	gintmsk_data_t intr_mask = {.d32 = 0};
539
540	num_in_eps = GET_CORE_IF(pcd)->dev_if->num_in_eps;
541	num_out_eps = GET_CORE_IF(pcd)->dev_if->num_out_eps;
542
543	DWC_DEBUGPL(DBG_PCDV, "%s() \n", __func__);
544	/* don't disconnect drivers more than once */
545	if (pcd->ep0state == EP0_DISCONNECT) {
546		DWC_DEBUGPL(DBG_ANY, "%s() Already Disconnected\n", __func__);
547		return;
548	}
549	pcd->ep0state = EP0_DISCONNECT;
550
551	/* Reset the OTG state. */
552	dwc_otg_pcd_update_otg(pcd, 1);
553
554	/* Disable the NP Tx Fifo Empty Interrupt. */
555	intr_mask.b.nptxfempty = 1;
556	dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
557					 intr_mask.d32, 0);
558
559	/* Flush the FIFOs */
560	/**@todo NGS Flush Periodic FIFOs */
561	dwc_otg_flush_tx_fifo(GET_CORE_IF(pcd), 0x10);
562	dwc_otg_flush_rx_fifo(GET_CORE_IF(pcd));
563
564	/* prevent new request submissions, kill any outstanding requests  */
565	ep = &pcd->ep0;
566	dwc_otg_request_nuke(ep);
567	/* prevent new request submissions, kill any outstanding requests  */
568	for (i = 0; i < num_in_eps; i++)
569	{
570		dwc_otg_pcd_ep_t *ep = &pcd->in_ep[i];
571		dwc_otg_request_nuke(ep);
572	}
573	/* prevent new request submissions, kill any outstanding requests  */
574	for (i = 0; i < num_out_eps; i++)
575	{
576		dwc_otg_pcd_ep_t *ep = &pcd->out_ep[i];
577		dwc_otg_request_nuke(ep);
578	}
579
580	/* report disconnect; the driver is already quiesced */
581	if (pcd->driver && pcd->driver->disconnect) {
582		SPIN_UNLOCK(&pcd->lock);
583		pcd->driver->disconnect(&pcd->gadget);
584		SPIN_LOCK(&pcd->lock);
585	}
586}
587
588/**
589 * This interrupt indicates that ...
590 */
591int32_t dwc_otg_pcd_handle_i2c_intr(dwc_otg_pcd_t *pcd)
592{
593	gintmsk_data_t intr_mask = { .d32 = 0};
594	gintsts_data_t gintsts;
595
596	DWC_PRINT("INTERRUPT Handler not implemented for %s\n", "i2cintr");
597	intr_mask.b.i2cintr = 1;
598	dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
599				intr_mask.d32, 0);
600
601	/* Clear interrupt */
602	gintsts.d32 = 0;
603	gintsts.b.i2cintr = 1;
604	dwc_write_reg32 (&GET_CORE_IF(pcd)->core_global_regs->gintsts,
605						 gintsts.d32);
606	return 1;
607}
608
609
610/**
611 * This interrupt indicates that ...
612 */
613int32_t dwc_otg_pcd_handle_early_suspend_intr(dwc_otg_pcd_t *pcd)
614{
615	gintsts_data_t gintsts;
616#if defined(VERBOSE)
617	DWC_PRINT("Early Suspend Detected\n");
618#endif
619	/* Clear interrupt */
620	gintsts.d32 = 0;
621	gintsts.b.erlysuspend = 1;
622	dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
623				gintsts.d32);
624	return 1;
625}
626
627/**
628 * This function configures EPO to receive SETUP packets.
629 *
630 * @todo NGS: Update the comments from the HW FS.
631 *
632 *	-# Program the following fields in the endpoint specific registers
633 *	for Control OUT EP 0, in order to receive a setup packet
634 *	- DOEPTSIZ0.Packet Count = 3 (To receive up to 3 back to back
635 *	  setup packets)
636 *	- DOEPTSIZE0.Transfer Size = 24 Bytes (To receive up to 3 back
637 *	  to back setup packets)
638 *		- In DMA mode, DOEPDMA0 Register with a memory address to
639 *		  store any setup packets received
640 *
641 * @param core_if Programming view of DWC_otg controller.
642 * @param pcd	  Programming view of the PCD.
643 */
644static inline void ep0_out_start(dwc_otg_core_if_t *core_if, dwc_otg_pcd_t *pcd)
645{
646	dwc_otg_dev_if_t *dev_if = core_if->dev_if;
647	deptsiz0_data_t doeptsize0 = { .d32 = 0};
648	dwc_otg_dma_desc_t* dma_desc;
649	depctl_data_t doepctl = { .d32 = 0 };
650
651#ifdef VERBOSE
652	DWC_DEBUGPL(DBG_PCDV,"%s() doepctl0=%0x\n", __func__,
653				dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl));
654#endif
655
656	doeptsize0.b.supcnt = 3;
657	doeptsize0.b.pktcnt = 1;
658	doeptsize0.b.xfersize = 8*3;
659
660
661	if (core_if->dma_enable) {
662		if (!core_if->dma_desc_enable) {
663			/** put here as for Hermes mode deptisz register should not be written */
664			dwc_write_reg32(&dev_if->out_ep_regs[0]->doeptsiz,
665			 doeptsize0.d32);
666
667			/** @todo dma needs to handle multiple setup packets (up to 3) */
668			dwc_write_reg32(&dev_if->out_ep_regs[0]->doepdma,
669			pcd->setup_pkt_dma_handle);
670		} else {
671			dev_if->setup_desc_index = (dev_if->setup_desc_index + 1) & 1;
672			dma_desc = dev_if->setup_desc_addr[dev_if->setup_desc_index];
673
674			/** DMA Descriptor Setup */
675			dma_desc->status.b.bs = BS_HOST_BUSY;
676			dma_desc->status.b.l = 1;
677			dma_desc->status.b.ioc = 1;
678			dma_desc->status.b.bytes = pcd->ep0.dwc_ep.maxpacket;
679			dma_desc->buf = pcd->setup_pkt_dma_handle;
680			dma_desc->status.b.bs = BS_HOST_READY;
681
682			/** DOEPDMA0 Register write */
683			dwc_write_reg32(&dev_if->out_ep_regs[0]->doepdma, dev_if->dma_setup_desc_addr[dev_if->setup_desc_index]);
684		}
685
686	} else {
687		/** put here as for Hermes mode deptisz register should not be written */
688		dwc_write_reg32(&dev_if->out_ep_regs[0]->doeptsiz,
689					 doeptsize0.d32);
690	}
691
692	/** DOEPCTL0 Register write */
693	doepctl.b.epena = 1;
694	doepctl.b.cnak = 1;
695	dwc_write_reg32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32);
696
697#ifdef VERBOSE
698	DWC_DEBUGPL(DBG_PCDV,"doepctl0=%0x\n",
699				dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl));
700	DWC_DEBUGPL(DBG_PCDV,"diepctl0=%0x\n",
701				dwc_read_reg32(&dev_if->in_ep_regs[0]->diepctl));
702#endif
703}
704
705
706/**
707 * This interrupt occurs when a USB Reset is detected.	When the USB
708 * Reset Interrupt occurs the device state is set to DEFAULT and the
709 * EP0 state is set to IDLE.
710 *	-#	Set the NAK bit for all OUT endpoints (DOEPCTLn.SNAK = 1)
711 *	-#	Unmask the following interrupt bits
712 *		- DAINTMSK.INEP0 = 1 (Control 0 IN endpoint)
713 *	- DAINTMSK.OUTEP0 = 1 (Control 0 OUT endpoint)
714 *	- DOEPMSK.SETUP = 1
715 *	- DOEPMSK.XferCompl = 1
716 *	- DIEPMSK.XferCompl = 1
717 *	- DIEPMSK.TimeOut = 1
718 *	-# Program the following fields in the endpoint specific registers
719 *	for Control OUT EP 0, in order to receive a setup packet
720 *	- DOEPTSIZ0.Packet Count = 3 (To receive up to 3 back to back
721 *	  setup packets)
722 *	- DOEPTSIZE0.Transfer Size = 24 Bytes (To receive up to 3 back
723 *	  to back setup packets)
724 *		- In DMA mode, DOEPDMA0 Register with a memory address to
725 *		  store any setup packets received
726 * At this point, all the required initialization, except for enabling
727 * the control 0 OUT endpoint is done, for receiving SETUP packets.
728 */
729int32_t dwc_otg_pcd_handle_usb_reset_intr(dwc_otg_pcd_t * pcd)
730{
731	dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
732	dwc_otg_dev_if_t *dev_if = core_if->dev_if;
733	depctl_data_t doepctl = { .d32 = 0};
734
735	daint_data_t daintmsk = { .d32 = 0};
736	doepmsk_data_t doepmsk = { .d32 = 0};
737	diepmsk_data_t diepmsk = { .d32 = 0};
738
739	dcfg_data_t dcfg = { .d32=0 };
740	grstctl_t resetctl = { .d32=0 };
741	dctl_data_t dctl = {.d32=0};
742	int i = 0;
743	gintsts_data_t gintsts;
744
745	DWC_PRINT("USB RESET\n");
746#ifdef DWC_EN_ISOC
747	for(i = 1;i < 16; ++i)
748	{
749		dwc_otg_pcd_ep_t *ep;
750		dwc_ep_t *dwc_ep;
751		ep = get_in_ep(pcd,i);
752		if(ep != 0){
753			dwc_ep = &ep->dwc_ep;
754			dwc_ep->next_frame = 0xffffffff;
755		}
756	}
757#endif /* DWC_EN_ISOC  */
758
759	/* reset the HNP settings */
760	dwc_otg_pcd_update_otg(pcd, 1);
761
762	/* Clear the Remote Wakeup Signalling */
763	dctl.b.rmtwkupsig = 1;
764	dwc_modify_reg32(&core_if->dev_if->dev_global_regs->dctl,
765					  dctl.d32, 0);
766
767	/* Set NAK for all OUT EPs */
768	doepctl.b.snak = 1;
769	for (i=0; i <= dev_if->num_out_eps; i++)
770	{
771		dwc_write_reg32(&dev_if->out_ep_regs[i]->doepctl,
772						 doepctl.d32);
773	}
774
775	/* Flush the NP Tx FIFO */
776	dwc_otg_flush_tx_fifo(core_if, 0x10);
777	/* Flush the Learning Queue */
778	resetctl.b.intknqflsh = 1;
779	dwc_write_reg32(&core_if->core_global_regs->grstctl, resetctl.d32);
780
781	if(core_if->multiproc_int_enable) {
782		daintmsk.b.inep0 = 1;
783		daintmsk.b.outep0 = 1;
784		dwc_write_reg32(&dev_if->dev_global_regs->deachintmsk, daintmsk.d32);
785
786		doepmsk.b.setup = 1;
787		doepmsk.b.xfercompl = 1;
788		doepmsk.b.ahberr = 1;
789		doepmsk.b.epdisabled = 1;
790
791		if(core_if->dma_desc_enable) {
792			doepmsk.b.stsphsercvd = 1;
793			doepmsk.b.bna = 1;
794		}
795/*
796		doepmsk.b.babble = 1;
797		doepmsk.b.nyet = 1;
798
799		if(core_if->dma_enable) {
800			doepmsk.b.nak = 1;
801		}
802*/
803		dwc_write_reg32(&dev_if->dev_global_regs->doepeachintmsk[0], doepmsk.d32);
804
805		diepmsk.b.xfercompl = 1;
806		diepmsk.b.timeout = 1;
807		diepmsk.b.epdisabled = 1;
808		diepmsk.b.ahberr = 1;
809		diepmsk.b.intknepmis = 1;
810
811		if(core_if->dma_desc_enable) {
812			diepmsk.b.bna = 1;
813		}
814/*
815		if(core_if->dma_enable) {
816			diepmsk.b.nak = 1;
817		}
818*/
819		dwc_write_reg32(&dev_if->dev_global_regs->diepeachintmsk[0], diepmsk.d32);
820	} else{
821		daintmsk.b.inep0 = 1;
822		daintmsk.b.outep0 = 1;
823		dwc_write_reg32(&dev_if->dev_global_regs->daintmsk, daintmsk.d32);
824
825		doepmsk.b.setup = 1;
826		doepmsk.b.xfercompl = 1;
827		doepmsk.b.ahberr = 1;
828		doepmsk.b.epdisabled = 1;
829
830		if(core_if->dma_desc_enable) {
831			doepmsk.b.stsphsercvd = 1;
832			doepmsk.b.bna = 1;
833		}
834/*
835		doepmsk.b.babble = 1;
836		doepmsk.b.nyet = 1;
837		doepmsk.b.nak = 1;
838*/
839		dwc_write_reg32(&dev_if->dev_global_regs->doepmsk, doepmsk.d32);
840
841		diepmsk.b.xfercompl = 1;
842		diepmsk.b.timeout = 1;
843		diepmsk.b.epdisabled = 1;
844		diepmsk.b.ahberr = 1;
845		diepmsk.b.intknepmis = 1;
846
847		if(core_if->dma_desc_enable) {
848			diepmsk.b.bna = 1;
849		}
850
851//		diepmsk.b.nak = 1;
852
853		dwc_write_reg32(&dev_if->dev_global_regs->diepmsk, diepmsk.d32);
854	}
855
856	/* Reset Device Address */
857	dcfg.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dcfg);
858	dcfg.b.devaddr = 0;
859	dwc_write_reg32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
860
861	/* setup EP0 to receive SETUP packets */
862	ep0_out_start(core_if, pcd);
863
864	/* Clear interrupt */
865	gintsts.d32 = 0;
866	gintsts.b.usbreset = 1;
867	dwc_write_reg32 (&core_if->core_global_regs->gintsts, gintsts.d32);
868
869	return 1;
870}
871
872/**
873 * Get the device speed from the device status register and convert it
874 * to USB speed constant.
875 *
876 * @param core_if Programming view of DWC_otg controller.
877 */
878static int get_device_speed(dwc_otg_core_if_t *core_if)
879{
880	dsts_data_t dsts;
881	enum usb_device_speed speed = USB_SPEED_UNKNOWN;
882	dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
883
884	switch (dsts.b.enumspd) {
885	case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
886		speed = USB_SPEED_HIGH;
887		break;
888	case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
889	case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
890		speed = USB_SPEED_FULL;
891		break;
892
893	case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
894		speed = USB_SPEED_LOW;
895		break;
896	}
897
898	return speed;
899}
900
901/**
902 * Read the device status register and set the device speed in the
903 * data structure.
904 * Set up EP0 to receive SETUP packets by calling dwc_ep0_activate.
905 */
906int32_t dwc_otg_pcd_handle_enum_done_intr(dwc_otg_pcd_t *pcd)
907{
908	dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
909	gintsts_data_t gintsts;
910	gusbcfg_data_t gusbcfg;
911	dwc_otg_core_global_regs_t *global_regs =
912		GET_CORE_IF(pcd)->core_global_regs;
913	uint8_t utmi16b, utmi8b;
914	DWC_DEBUGPL(DBG_PCD, "SPEED ENUM\n");
915
916	if (GET_CORE_IF(pcd)->snpsid >= 0x4F54260A) {
917		utmi16b = 6;
918		utmi8b = 9;
919	} else {
920		utmi16b = 4;
921		utmi8b = 8;
922	}
923	dwc_otg_ep0_activate(GET_CORE_IF(pcd), &ep0->dwc_ep);
924
925#ifdef DEBUG_EP0
926	print_ep0_state(pcd);
927#endif
928
929	if (pcd->ep0state == EP0_DISCONNECT) {
930		pcd->ep0state = EP0_IDLE;
931	}
932	else if (pcd->ep0state == EP0_STALL) {
933		pcd->ep0state = EP0_IDLE;
934	}
935
936	pcd->ep0state = EP0_IDLE;
937
938	ep0->stopped = 0;
939
940	pcd->gadget.speed = get_device_speed(GET_CORE_IF(pcd));
941
942	/* Set USB turnaround time based on device speed and PHY interface. */
943	gusbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
944	if (pcd->gadget.speed == USB_SPEED_HIGH) {
945		if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type == DWC_HWCFG2_HS_PHY_TYPE_ULPI) {
946			/* ULPI interface */
947			gusbcfg.b.usbtrdtim = 9;
948		}
949		if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type == DWC_HWCFG2_HS_PHY_TYPE_UTMI) {
950			/* UTMI+ interface */
951			if (GET_CORE_IF(pcd)->hwcfg4.b.utmi_phy_data_width == 0) {
952				gusbcfg.b.usbtrdtim = utmi8b;
953			}
954			else if (GET_CORE_IF(pcd)->hwcfg4.b.utmi_phy_data_width == 1) {
955				gusbcfg.b.usbtrdtim = utmi16b;
956			}
957			else if (GET_CORE_IF(pcd)->core_params->phy_utmi_width == 8) {
958				gusbcfg.b.usbtrdtim = utmi8b;
959			}
960			else {
961				gusbcfg.b.usbtrdtim = utmi16b;
962			}
963		}
964		if (GET_CORE_IF(pcd)->hwcfg2.b.hs_phy_type == DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI) {
965			/* UTMI+  OR  ULPI interface */
966			if (gusbcfg.b.ulpi_utmi_sel == 1) {
967				/* ULPI interface */
968				gusbcfg.b.usbtrdtim = 9;
969			}
970			else {
971				/* UTMI+ interface */
972				if (GET_CORE_IF(pcd)->core_params->phy_utmi_width == 16) {
973					gusbcfg.b.usbtrdtim = utmi16b;
974				}
975				else {
976					gusbcfg.b.usbtrdtim = utmi8b;
977				}
978			}
979		}
980	}
981	else {
982		/* Full or low speed */
983		gusbcfg.b.usbtrdtim = 9;
984	}
985	dwc_write_reg32(&global_regs->gusbcfg, gusbcfg.d32);
986
987	/* Clear interrupt */
988	gintsts.d32 = 0;
989	gintsts.b.enumdone = 1;
990	dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
991			 gintsts.d32);
992	return 1;
993}
994
995/**
996 * This interrupt indicates that the ISO OUT Packet was dropped due to
997 * Rx FIFO full or Rx Status Queue Full.  If this interrupt occurs
998 * read all the data from the Rx FIFO.
999 */
1000int32_t dwc_otg_pcd_handle_isoc_out_packet_dropped_intr(dwc_otg_pcd_t *pcd)
1001{
1002	gintmsk_data_t intr_mask = { .d32 = 0};
1003	gintsts_data_t gintsts;
1004
1005	DWC_PRINT("INTERRUPT Handler not implemented for %s\n",
1006			  "ISOC Out Dropped");
1007
1008	intr_mask.b.isooutdrop = 1;
1009	dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
1010			  intr_mask.d32, 0);
1011
1012	/* Clear interrupt */
1013
1014	gintsts.d32 = 0;
1015	gintsts.b.isooutdrop = 1;
1016	dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
1017			 gintsts.d32);
1018
1019	return 1;
1020}
1021
1022/**
1023 * This interrupt indicates the end of the portion of the micro-frame
1024 * for periodic transactions.  If there is a periodic transaction for
1025 * the next frame, load the packets into the EP periodic Tx FIFO.
1026 */
1027int32_t dwc_otg_pcd_handle_end_periodic_frame_intr(dwc_otg_pcd_t *pcd)
1028{
1029	gintmsk_data_t intr_mask = { .d32 = 0};
1030	gintsts_data_t gintsts;
1031	DWC_PRINT("INTERRUPT Handler not implemented for %s\n", "EOP");
1032
1033	intr_mask.b.eopframe = 1;
1034	dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
1035					  intr_mask.d32, 0);
1036
1037	/* Clear interrupt */
1038	gintsts.d32 = 0;
1039	gintsts.b.eopframe = 1;
1040	dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts, gintsts.d32);
1041
1042	return 1;
1043}
1044
1045/**
1046 * This interrupt indicates that EP of the packet on the top of the
1047 * non-periodic Tx FIFO does not match EP of the IN Token received.
1048 *
1049 * The "Device IN Token Queue" Registers are read to determine the
1050 * order the IN Tokens have been received.	The non-periodic Tx FIFO
1051 * is flushed, so it can be reloaded in the order seen in the IN Token
1052 * Queue.
1053 */
1054int32_t dwc_otg_pcd_handle_ep_mismatch_intr(dwc_otg_core_if_t *core_if)
1055{
1056	gintsts_data_t gintsts;
1057	DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, core_if);
1058
1059	/* Clear interrupt */
1060	gintsts.d32 = 0;
1061	gintsts.b.epmismatch = 1;
1062	dwc_write_reg32 (&core_if->core_global_regs->gintsts, gintsts.d32);
1063
1064	return 1;
1065}
1066
1067/**
1068 * This funcion stalls EP0.
1069 */
1070static inline void ep0_do_stall(dwc_otg_pcd_t *pcd, const int err_val)
1071{
1072	dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
1073	struct usb_ctrlrequest	*ctrl = &pcd->setup_pkt->req;
1074	DWC_WARN("req %02x.%02x protocol STALL; err %d\n",
1075			 ctrl->bRequestType, ctrl->bRequest, err_val);
1076
1077	ep0->dwc_ep.is_in = 1;
1078	dwc_otg_ep_set_stall(pcd->otg_dev->core_if, &ep0->dwc_ep);
1079	pcd->ep0.stopped = 1;
1080	pcd->ep0state = EP0_IDLE;
1081	ep0_out_start(GET_CORE_IF(pcd), pcd);
1082}
1083
1084/**
1085 * This functions delegates the setup command to the gadget driver.
1086 */
1087static inline void do_gadget_setup(dwc_otg_pcd_t *pcd,
1088					struct usb_ctrlrequest * ctrl)
1089{
1090	int ret = 0;
1091	if (pcd->driver && pcd->driver->setup) {
1092		SPIN_UNLOCK(&pcd->lock);
1093		ret = pcd->driver->setup(&pcd->gadget, ctrl);
1094		SPIN_LOCK(&pcd->lock);
1095		if (ret < 0) {
1096			ep0_do_stall(pcd, ret);
1097		}
1098
1099		/** @todo This is a g_file_storage gadget driver specific
1100		 * workaround: a DELAYED_STATUS result from the fsg_setup
1101		 * routine will result in the gadget queueing a EP0 IN status
1102		 * phase for a two-stage control transfer.	Exactly the same as
1103		 * a SET_CONFIGURATION/SET_INTERFACE except that this is a class
1104		 * specific request.  Need a generic way to know when the gadget
1105		 * driver will queue the status phase.	Can we assume when we
1106		 * call the gadget driver setup() function that it will always
1107		 * queue and require the following flag?  Need to look into
1108		 * this.
1109		 */
1110
1111		if (ret == 256 + 999) {
1112			pcd->request_config = 1;
1113		}
1114	}
1115}
1116
1117/**
1118 * This function starts the Zero-Length Packet for the IN status phase
1119 * of a 2 stage control transfer.
1120 */
1121static inline void do_setup_in_status_phase(dwc_otg_pcd_t *pcd)
1122{
1123	dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
1124	if (pcd->ep0state == EP0_STALL) {
1125		return;
1126	}
1127
1128	pcd->ep0state = EP0_IN_STATUS_PHASE;
1129
1130	/* Prepare for more SETUP Packets */
1131	DWC_DEBUGPL(DBG_PCD, "EP0 IN ZLP\n");
1132	ep0->dwc_ep.xfer_len = 0;
1133	ep0->dwc_ep.xfer_count = 0;
1134	ep0->dwc_ep.is_in = 1;
1135	ep0->dwc_ep.dma_addr = pcd->setup_pkt_dma_handle;
1136	dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
1137
1138	/* Prepare for more SETUP Packets */
1139//	if(GET_CORE_IF(pcd)->dma_enable == 0) ep0_out_start(GET_CORE_IF(pcd), pcd);
1140}
1141
1142/**
1143 * This function starts the Zero-Length Packet for the OUT status phase
1144 * of a 2 stage control transfer.
1145 */
1146static inline void do_setup_out_status_phase(dwc_otg_pcd_t *pcd)
1147{
1148	dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
1149	if (pcd->ep0state == EP0_STALL) {
1150		DWC_DEBUGPL(DBG_PCD, "EP0 STALLED\n");
1151		return;
1152	}
1153	pcd->ep0state = EP0_OUT_STATUS_PHASE;
1154
1155	DWC_DEBUGPL(DBG_PCD, "EP0 OUT ZLP\n");
1156	ep0->dwc_ep.xfer_len = 0;
1157	ep0->dwc_ep.xfer_count = 0;
1158	ep0->dwc_ep.is_in = 0;
1159	ep0->dwc_ep.dma_addr = pcd->setup_pkt_dma_handle;
1160	dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
1161
1162	/* Prepare for more SETUP Packets */
1163	if(GET_CORE_IF(pcd)->dma_enable == 0) {
1164			ep0_out_start(GET_CORE_IF(pcd), pcd);
1165	}
1166}
1167
1168/**
1169 * Clear the EP halt (STALL) and if pending requests start the
1170 * transfer.
1171 */
1172static inline void pcd_clear_halt(dwc_otg_pcd_t *pcd, dwc_otg_pcd_ep_t *ep)
1173{
1174	if(ep->dwc_ep.stall_clear_flag == 0)
1175		dwc_otg_ep_clear_stall(GET_CORE_IF(pcd), &ep->dwc_ep);
1176
1177	/* Reactive the EP */
1178	dwc_otg_ep_activate(GET_CORE_IF(pcd), &ep->dwc_ep);
1179	if (ep->stopped) {
1180		ep->stopped = 0;
1181		/* If there is a request in the EP queue start it */
1182
1183		/** @todo FIXME: this causes an EP mismatch in DMA mode.
1184		 * epmismatch not yet implemented. */
1185
1186		/*
1187		 * Above fixme is solved by implmenting a tasklet to call the
1188		 * start_next_request(), outside of interrupt context at some
1189		 * time after the current time, after a clear-halt setup packet.
1190		 * Still need to implement ep mismatch in the future if a gadget
1191		 * ever uses more than one endpoint at once
1192		 */
1193		ep->queue_sof = 1;
1194		tasklet_schedule (pcd->start_xfer_tasklet);
1195	}
1196	/* Start Control Status Phase */
1197	do_setup_in_status_phase(pcd);
1198}
1199
1200/**
1201 * This function is called when the SET_FEATURE TEST_MODE Setup packet
1202 * is sent from the host.  The Device Control register is written with
1203 * the Test Mode bits set to the specified Test Mode.  This is done as
1204 * a tasklet so that the "Status" phase of the control transfer
1205 * completes before transmitting the TEST packets.
1206 *
1207 * @todo This has not been tested since the tasklet struct was put
1208 * into the PCD struct!
1209 *
1210 */
1211static void do_test_mode(unsigned long data)
1212{
1213	dctl_data_t		dctl;
1214	dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)data;
1215	dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
1216	int test_mode = pcd->test_mode;
1217
1218
1219//	  DWC_WARN("%s() has not been tested since being rewritten!\n", __func__);
1220
1221	dctl.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dctl);
1222	switch (test_mode) {
1223	case 1: // TEST_J
1224		dctl.b.tstctl = 1;
1225		break;
1226
1227	case 2: // TEST_K
1228		dctl.b.tstctl = 2;
1229		break;
1230
1231	case 3: // TEST_SE0_NAK
1232		dctl.b.tstctl = 3;
1233		break;
1234
1235	case 4: // TEST_PACKET
1236		dctl.b.tstctl = 4;
1237		break;
1238
1239	case 5: // TEST_FORCE_ENABLE
1240		dctl.b.tstctl = 5;
1241		break;
1242	}
1243	dwc_write_reg32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
1244}
1245
1246/**
1247 * This function process the GET_STATUS Setup Commands.
1248 */
1249static inline void do_get_status(dwc_otg_pcd_t *pcd)
1250{
1251	struct usb_ctrlrequest	ctrl = pcd->setup_pkt->req;
1252	dwc_otg_pcd_ep_t	*ep;
1253	dwc_otg_pcd_ep_t	*ep0 = &pcd->ep0;
1254	uint16_t		*status = pcd->status_buf;
1255
1256#ifdef DEBUG_EP0
1257	DWC_DEBUGPL(DBG_PCD,
1258			"GET_STATUS %02x.%02x v%04x i%04x l%04x\n",
1259			ctrl.bRequestType, ctrl.bRequest,
1260			ctrl.wValue, ctrl.wIndex, ctrl.wLength);
1261#endif
1262
1263	switch (ctrl.bRequestType & USB_RECIP_MASK) {
1264	case USB_RECIP_DEVICE:
1265		*status = 0x1; /* Self powered */
1266		*status |= pcd->remote_wakeup_enable << 1;
1267		break;
1268
1269	case USB_RECIP_INTERFACE:
1270		*status = 0;
1271		break;
1272
1273	case USB_RECIP_ENDPOINT:
1274		ep = get_ep_by_addr(pcd, ctrl.wIndex);
1275		if (ep == 0 || ctrl.wLength > 2) {
1276			ep0_do_stall(pcd, -EOPNOTSUPP);
1277			return;
1278		}
1279		/** @todo check for EP stall */
1280		*status = ep->stopped;
1281		break;
1282	}
1283	pcd->ep0_pending = 1;
1284	ep0->dwc_ep.start_xfer_buff = (uint8_t *)status;
1285	ep0->dwc_ep.xfer_buff = (uint8_t *)status;
1286	ep0->dwc_ep.dma_addr = pcd->status_buf_dma_handle;
1287	ep0->dwc_ep.xfer_len = 2;
1288	ep0->dwc_ep.xfer_count = 0;
1289	ep0->dwc_ep.total_len = ep0->dwc_ep.xfer_len;
1290	dwc_otg_ep0_start_transfer(GET_CORE_IF(pcd), &ep0->dwc_ep);
1291}
1292/**
1293 * This function process the SET_FEATURE Setup Commands.
1294 */
1295static inline void do_set_feature(dwc_otg_pcd_t *pcd)
1296{
1297	dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
1298	dwc_otg_core_global_regs_t *global_regs =
1299			core_if->core_global_regs;
1300	struct usb_ctrlrequest	ctrl = pcd->setup_pkt->req;
1301	dwc_otg_pcd_ep_t	*ep = 0;
1302	int32_t otg_cap_param = core_if->core_params->otg_cap;
1303	gotgctl_data_t gotgctl = { .d32 = 0 };
1304
1305	DWC_DEBUGPL(DBG_PCD, "SET_FEATURE:%02x.%02x v%04x i%04x l%04x\n",
1306			ctrl.bRequestType, ctrl.bRequest,
1307			ctrl.wValue, ctrl.wIndex, ctrl.wLength);
1308	DWC_DEBUGPL(DBG_PCD,"otg_cap=%d\n", otg_cap_param);
1309
1310
1311	switch (ctrl.bRequestType & USB_RECIP_MASK) {
1312	case USB_RECIP_DEVICE:
1313		switch (ctrl.wValue) {
1314		case USB_DEVICE_REMOTE_WAKEUP:
1315			pcd->remote_wakeup_enable = 1;
1316			break;
1317
1318		case USB_DEVICE_TEST_MODE:
1319			/* Setup the Test Mode tasklet to do the Test
1320			 * Packet generation after the SETUP Status
1321			 * phase has completed. */
1322
1323			/** @todo This has not been tested since the
1324			 * tasklet struct was put into the PCD
1325			 * struct! */
1326			pcd->test_mode_tasklet.next = 0;
1327			pcd->test_mode_tasklet.state = 0;
1328			atomic_set(&pcd->test_mode_tasklet.count, 0);
1329			pcd->test_mode_tasklet.func = do_test_mode;
1330			pcd->test_mode_tasklet.data = (unsigned long)pcd;
1331			pcd->test_mode = ctrl.wIndex >> 8;
1332			tasklet_schedule(&pcd->test_mode_tasklet);
1333			break;
1334
1335		case USB_DEVICE_B_HNP_ENABLE:
1336			DWC_DEBUGPL(DBG_PCDV, "SET_FEATURE: USB_DEVICE_B_HNP_ENABLE\n");
1337
1338			/* dev may initiate HNP */
1339			if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
1340				pcd->b_hnp_enable = 1;
1341				dwc_otg_pcd_update_otg(pcd, 0);
1342				DWC_DEBUGPL(DBG_PCD, "Request B HNP\n");
1343				/**@todo Is the gotgctl.devhnpen cleared
1344				 * by a USB Reset? */
1345				gotgctl.b.devhnpen = 1;
1346				gotgctl.b.hnpreq = 1;
1347				dwc_write_reg32(&global_regs->gotgctl, gotgctl.d32);
1348			}
1349			else {
1350				ep0_do_stall(pcd, -EOPNOTSUPP);
1351			}
1352			break;
1353
1354		case USB_DEVICE_A_HNP_SUPPORT:
1355			/* RH port supports HNP */
1356			DWC_DEBUGPL(DBG_PCDV, "SET_FEATURE: USB_DEVICE_A_HNP_SUPPORT\n");
1357			if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
1358				pcd->a_hnp_support = 1;
1359				dwc_otg_pcd_update_otg(pcd, 0);
1360			}
1361			else {
1362				ep0_do_stall(pcd, -EOPNOTSUPP);
1363			}
1364			break;
1365
1366		case USB_DEVICE_A_ALT_HNP_SUPPORT:
1367			/* other RH port does */
1368			DWC_DEBUGPL(DBG_PCDV, "SET_FEATURE: USB_DEVICE_A_ALT_HNP_SUPPORT\n");
1369			if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE) {
1370				pcd->a_alt_hnp_support = 1;
1371				dwc_otg_pcd_update_otg(pcd, 0);
1372			}
1373			else {
1374				ep0_do_stall(pcd, -EOPNOTSUPP);
1375			}
1376			break;
1377		}
1378		do_setup_in_status_phase(pcd);
1379		break;
1380
1381	case USB_RECIP_INTERFACE:
1382		do_gadget_setup(pcd, &ctrl);
1383		break;
1384
1385	case USB_RECIP_ENDPOINT:
1386		if (ctrl.wValue == USB_ENDPOINT_HALT) {
1387			ep = get_ep_by_addr(pcd, ctrl.wIndex);
1388			if (ep == 0) {
1389				ep0_do_stall(pcd, -EOPNOTSUPP);
1390				return;
1391			}
1392			ep->stopped = 1;
1393			dwc_otg_ep_set_stall(core_if, &ep->dwc_ep);
1394		}
1395		do_setup_in_status_phase(pcd);
1396		break;
1397	}
1398}
1399
1400/**
1401 * This function process the CLEAR_FEATURE Setup Commands.
1402 */
1403static inline void do_clear_feature(dwc_otg_pcd_t *pcd)
1404{
1405	struct usb_ctrlrequest	ctrl = pcd->setup_pkt->req;
1406	dwc_otg_pcd_ep_t	*ep = 0;
1407
1408	DWC_DEBUGPL(DBG_PCD,
1409				"CLEAR_FEATURE:%02x.%02x v%04x i%04x l%04x\n",
1410				ctrl.bRequestType, ctrl.bRequest,
1411				ctrl.wValue, ctrl.wIndex, ctrl.wLength);
1412
1413	switch (ctrl.bRequestType & USB_RECIP_MASK) {
1414	case USB_RECIP_DEVICE:
1415		switch (ctrl.wValue) {
1416		case USB_DEVICE_REMOTE_WAKEUP:
1417			pcd->remote_wakeup_enable = 0;
1418			break;
1419
1420		case USB_DEVICE_TEST_MODE:
1421			/** @todo Add CLEAR_FEATURE for TEST modes. */
1422			break;
1423		}
1424		do_setup_in_status_phase(pcd);
1425		break;
1426
1427	case USB_RECIP_ENDPOINT:
1428		ep = get_ep_by_addr(pcd, ctrl.wIndex);
1429		if (ep == 0) {
1430			ep0_do_stall(pcd, -EOPNOTSUPP);
1431			return;
1432		}
1433
1434		pcd_clear_halt(pcd, ep);
1435
1436		break;
1437	}
1438}
1439
1440/**
1441 * This function process the SET_ADDRESS Setup Commands.
1442 */
1443static inline void do_set_address(dwc_otg_pcd_t *pcd)
1444{
1445	dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
1446	struct usb_ctrlrequest	ctrl = pcd->setup_pkt->req;
1447
1448	if (ctrl.bRequestType == USB_RECIP_DEVICE) {
1449		dcfg_data_t dcfg = {.d32=0};
1450
1451#ifdef DEBUG_EP0
1452//			DWC_DEBUGPL(DBG_PCDV, "SET_ADDRESS:%d\n", ctrl.wValue);
1453#endif
1454		dcfg.b.devaddr = ctrl.wValue;
1455		dwc_modify_reg32(&dev_if->dev_global_regs->dcfg, 0, dcfg.d32);
1456		do_setup_in_status_phase(pcd);
1457	}
1458}
1459
1460/**
1461 *	This function processes SETUP commands.	 In Linux, the USB Command
1462 *	processing is done in two places - the first being the PCD and the
1463 *	second in the Gadget Driver (for example, the File-Backed Storage
1464 *	Gadget Driver).
1465 *
1466 * <table>
1467 * <tr><td>Command	</td><td>Driver </td><td>Description</td></tr>
1468 *
1469 * <tr><td>GET_STATUS </td><td>PCD </td><td>Command is processed as
1470 * defined in chapter 9 of the USB 2.0 Specification chapter 9
1471 * </td></tr>
1472 *
1473 * <tr><td>CLEAR_FEATURE </td><td>PCD </td><td>The Device and Endpoint
1474 * requests are the ENDPOINT_HALT feature is procesed, all others the
1475 * interface requests are ignored.</td></tr>
1476 *
1477 * <tr><td>SET_FEATURE </td><td>PCD </td><td>The Device and Endpoint
1478 * requests are processed by the PCD.  Interface requests are passed
1479 * to the Gadget Driver.</td></tr>
1480 *
1481 * <tr><td>SET_ADDRESS </td><td>PCD </td><td>Program the DCFG reg,
1482 * with device address received </td></tr>
1483 *
1484 * <tr><td>GET_DESCRIPTOR </td><td>Gadget Driver </td><td>Return the
1485 * requested descriptor</td></tr>
1486 *
1487 * <tr><td>SET_DESCRIPTOR </td><td>Gadget Driver </td><td>Optional -
1488 * not implemented by any of the existing Gadget Drivers.</td></tr>
1489 *
1490 * <tr><td>SET_CONFIGURATION </td><td>Gadget Driver </td><td>Disable
1491 * all EPs and enable EPs for new configuration.</td></tr>
1492 *
1493 * <tr><td>GET_CONFIGURATION </td><td>Gadget Driver </td><td>Return
1494 * the current configuration</td></tr>
1495 *
1496 * <tr><td>SET_INTERFACE </td><td>Gadget Driver </td><td>Disable all
1497 * EPs and enable EPs for new configuration.</td></tr>
1498 *
1499 * <tr><td>GET_INTERFACE </td><td>Gadget Driver </td><td>Return the
1500 * current interface.</td></tr>
1501 *
1502 * <tr><td>SYNC_FRAME </td><td>PCD </td><td>Display debug
1503 * message.</td></tr>
1504 * </table>
1505 *
1506 * When the SETUP Phase Done interrupt occurs, the PCD SETUP commands are
1507 * processed by pcd_setup. Calling the Function Driver's setup function from
1508 * pcd_setup processes the gadget SETUP commands.
1509 */
1510static inline void pcd_setup(dwc_otg_pcd_t *pcd)
1511{
1512	dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
1513	dwc_otg_dev_if_t *dev_if = core_if->dev_if;
1514	struct usb_ctrlrequest	ctrl = pcd->setup_pkt->req;
1515	dwc_otg_pcd_ep_t	*ep0 = &pcd->ep0;
1516
1517	deptsiz0_data_t doeptsize0 = { .d32 = 0};
1518
1519#ifdef DEBUG_EP0
1520	DWC_DEBUGPL(DBG_PCD, "SETUP %02x.%02x v%04x i%04x l%04x\n",
1521			ctrl.bRequestType, ctrl.bRequest,
1522			ctrl.wValue, ctrl.wIndex, ctrl.wLength);
1523#endif
1524
1525	doeptsize0.d32 = dwc_read_reg32(&dev_if->out_ep_regs[0]->doeptsiz);
1526
1527	/** @todo handle > 1 setup packet , assert error for now */
1528
1529	if (core_if->dma_enable && core_if->dma_desc_enable == 0 && (doeptsize0.b.supcnt < 2)) {
1530		DWC_ERROR ("\n\n-----------	 CANNOT handle > 1 setup packet in DMA mode\n\n");
1531	}
1532
1533	/* Clean up the request queue */
1534	dwc_otg_request_nuke(ep0);
1535	ep0->stopped = 0;
1536
1537	if (ctrl.bRequestType & USB_DIR_IN) {
1538		ep0->dwc_ep.is_in = 1;
1539		pcd->ep0state = EP0_IN_DATA_PHASE;
1540	}
1541	else {
1542		ep0->dwc_ep.is_in = 0;
1543		pcd->ep0state = EP0_OUT_DATA_PHASE;
1544	}
1545
1546	if(ctrl.wLength == 0) {
1547		ep0->dwc_ep.is_in = 1;
1548		pcd->ep0state = EP0_IN_STATUS_PHASE;
1549	}
1550
1551	if ((ctrl.bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD) {
1552		/* handle non-standard (class/vendor) requests in the gadget driver */
1553		do_gadget_setup(pcd, &ctrl);
1554		return;
1555	}
1556
1557	/** @todo NGS: Handle bad setup packet? */
1558
1559///////////////////////////////////////////
1560//// --- Standard Request handling --- ////
1561
1562	switch (ctrl.bRequest) {
1563		case USB_REQ_GET_STATUS:
1564		do_get_status(pcd);
1565		break;
1566
1567	case USB_REQ_CLEAR_FEATURE:
1568		do_clear_feature(pcd);
1569		break;
1570
1571	case USB_REQ_SET_FEATURE:
1572		do_set_feature(pcd);
1573		break;
1574
1575	case USB_REQ_SET_ADDRESS:
1576		do_set_address(pcd);
1577		break;
1578
1579	case USB_REQ_SET_INTERFACE:
1580	case USB_REQ_SET_CONFIGURATION:
1581//		_pcd->request_config = 1;	/* Configuration changed */
1582		do_gadget_setup(pcd, &ctrl);
1583		break;
1584
1585	case USB_REQ_SYNCH_FRAME:
1586		do_gadget_setup(pcd, &ctrl);
1587		break;
1588
1589	default:
1590		/* Call the Gadget Driver's setup functions */
1591		do_gadget_setup(pcd, &ctrl);
1592		break;
1593	}
1594}
1595
1596/**
1597 * This function completes the ep0 control transfer.
1598 */
1599static int32_t ep0_complete_request(dwc_otg_pcd_ep_t *ep)
1600{
1601	dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
1602	dwc_otg_dev_if_t *dev_if = core_if->dev_if;
1603	dwc_otg_dev_in_ep_regs_t *in_ep_regs =
1604	dev_if->in_ep_regs[ep->dwc_ep.num];
1605#ifdef DEBUG_EP0
1606	dwc_otg_dev_out_ep_regs_t *out_ep_regs =
1607			dev_if->out_ep_regs[ep->dwc_ep.num];
1608#endif
1609	deptsiz0_data_t deptsiz;
1610	desc_sts_data_t desc_sts;
1611	dwc_otg_pcd_request_t *req;
1612	int is_last = 0;
1613	dwc_otg_pcd_t *pcd = ep->pcd;
1614
1615	//DWC_DEBUGPL(DBG_PCDV, "%s() %s\n", __func__, _ep->ep.name);
1616
1617	if (pcd->ep0_pending && list_empty(&ep->queue)) {
1618		if (ep->dwc_ep.is_in) {
1619#ifdef DEBUG_EP0
1620			DWC_DEBUGPL(DBG_PCDV, "Do setup OUT status phase\n");
1621#endif
1622			do_setup_out_status_phase(pcd);
1623		}
1624		else {
1625#ifdef DEBUG_EP0
1626			DWC_DEBUGPL(DBG_PCDV, "Do setup IN status phase\n");
1627#endif
1628			do_setup_in_status_phase(pcd);
1629		}
1630		pcd->ep0_pending = 0;
1631		return 1;
1632	}
1633
1634	if (list_empty(&ep->queue)) {
1635		return 0;
1636	}
1637	req = list_entry(ep->queue.next, dwc_otg_pcd_request_t, queue);
1638
1639
1640	if (pcd->ep0state == EP0_OUT_STATUS_PHASE || pcd->ep0state == EP0_IN_STATUS_PHASE) {
1641		is_last = 1;
1642	}
1643	else if (ep->dwc_ep.is_in) {
1644		deptsiz.d32 = dwc_read_reg32(&in_ep_regs->dieptsiz);
1645		if(core_if->dma_desc_enable != 0)
1646			desc_sts.d32 = readl(dev_if->in_desc_addr);
1647#ifdef DEBUG_EP0
1648		DWC_DEBUGPL(DBG_PCDV, "%s len=%d  xfersize=%d pktcnt=%d\n",
1649				ep->ep.name, ep->dwc_ep.xfer_len,
1650				deptsiz.b.xfersize, deptsiz.b.pktcnt);
1651#endif
1652
1653		if (((core_if->dma_desc_enable == 0) && (deptsiz.b.xfersize == 0)) ||
1654			((core_if->dma_desc_enable != 0) && (desc_sts.b.bytes == 0))) {
1655			req->req.actual = ep->dwc_ep.xfer_count;
1656			/* Is a Zero Len Packet needed? */
1657			if (req->req.zero) {
1658#ifdef DEBUG_EP0
1659				DWC_DEBUGPL(DBG_PCD, "Setup Rx ZLP\n");
1660#endif
1661			    req->req.zero = 0;
1662			}
1663			do_setup_out_status_phase(pcd);
1664		}
1665	}
1666	else {
1667		/* ep0-OUT */
1668#ifdef DEBUG_EP0
1669		deptsiz.d32 = dwc_read_reg32(&out_ep_regs->doeptsiz);
1670		DWC_DEBUGPL(DBG_PCDV, "%s len=%d xsize=%d pktcnt=%d\n",
1671				ep->ep.name, ep->dwc_ep.xfer_len,
1672				deptsiz.b.xfersize,
1673				deptsiz.b.pktcnt);
1674#endif
1675		req->req.actual = ep->dwc_ep.xfer_count;
1676		/* Is a Zero Len Packet needed? */
1677		if (req->req.zero) {
1678#ifdef DEBUG_EP0
1679			DWC_DEBUGPL(DBG_PCDV, "Setup Tx ZLP\n");
1680#endif
1681    			req->req.zero = 0;
1682		}
1683		if(core_if->dma_desc_enable == 0)
1684			do_setup_in_status_phase(pcd);
1685	}
1686
1687	/* Complete the request */
1688	if (is_last) {
1689		dwc_otg_request_done(ep, req, 0);
1690		ep->dwc_ep.start_xfer_buff = 0;
1691		ep->dwc_ep.xfer_buff = 0;
1692		ep->dwc_ep.xfer_len = 0;
1693		return 1;
1694	}
1695	return 0;
1696}
1697
1698/**
1699 * This function completes the request for the EP.	If there are
1700 * additional requests for the EP in the queue they will be started.
1701 */
1702static void complete_ep(dwc_otg_pcd_ep_t *ep)
1703{
1704	dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
1705	dwc_otg_dev_if_t *dev_if = core_if->dev_if;
1706	dwc_otg_dev_in_ep_regs_t *in_ep_regs =
1707	dev_if->in_ep_regs[ep->dwc_ep.num];
1708	deptsiz_data_t deptsiz;
1709	desc_sts_data_t desc_sts;
1710	dwc_otg_pcd_request_t *req = 0;
1711	dwc_otg_dma_desc_t* dma_desc;
1712	uint32_t byte_count = 0;
1713	int is_last = 0;
1714	int i;
1715
1716	DWC_DEBUGPL(DBG_PCDV,"%s() %s-%s\n", __func__, ep->ep.name,
1717					(ep->dwc_ep.is_in?"IN":"OUT"));
1718
1719	/* Get any pending requests */
1720	if (!list_empty(&ep->queue)) {
1721		req = list_entry(ep->queue.next, dwc_otg_pcd_request_t,
1722				 queue);
1723		if (!req) {
1724			printk("complete_ep 0x%p, req = NULL!\n", ep);
1725			return;
1726		}
1727	}
1728	else {
1729		printk("complete_ep 0x%p, ep->queue empty!\n", ep);
1730		return;
1731	}
1732	DWC_DEBUGPL(DBG_PCD, "Requests %d\n", ep->pcd->request_pending);
1733
1734	if (ep->dwc_ep.is_in) {
1735		deptsiz.d32 = dwc_read_reg32(&in_ep_regs->dieptsiz);
1736
1737		if (core_if->dma_enable) {
1738			if(core_if->dma_desc_enable == 0) {
1739				if (deptsiz.b.xfersize == 0 && deptsiz.b.pktcnt == 0) {
1740					byte_count = ep->dwc_ep.xfer_len - ep->dwc_ep.xfer_count;
1741
1742					ep->dwc_ep.xfer_buff += byte_count;
1743					ep->dwc_ep.dma_addr += byte_count;
1744					ep->dwc_ep.xfer_count += byte_count;
1745
1746				DWC_DEBUGPL(DBG_PCDV, "%s len=%d  xfersize=%d pktcnt=%d\n",
1747						ep->ep.name, ep->dwc_ep.xfer_len,
1748						deptsiz.b.xfersize, deptsiz.b.pktcnt);
1749
1750
1751					if(ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
1752						dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
1753					} else if(ep->dwc_ep.sent_zlp) {
1754						/*
1755						 * This fragment of code should initiate 0
1756						 * length trasfer in case if it is queued
1757						 * a trasfer with size divisible to EPs max
1758						 * packet size and with usb_request zero field
1759						 * is set, which means that after data is transfered,
1760						 * it is also should be transfered
1761						 * a 0 length packet at the end. For Slave and
1762						 * Buffer DMA modes in this case SW has
1763						 * to initiate 2 transfers one with transfer size,
1764						 * and the second with 0 size. For Desriptor
1765						 * DMA mode SW is able to initiate a transfer,
1766						 * which will handle all the packets including
1767						 * the last  0 legth.
1768						 */
1769						ep->dwc_ep.sent_zlp = 0;
1770						dwc_otg_ep_start_zl_transfer(core_if, &ep->dwc_ep);
1771					} else {
1772						is_last = 1;
1773					}
1774				} else {
1775					DWC_WARN("Incomplete transfer (%s-%s [siz=%d pkt=%d])\n",
1776							 ep->ep.name, (ep->dwc_ep.is_in?"IN":"OUT"),
1777							 deptsiz.b.xfersize, deptsiz.b.pktcnt);
1778				}
1779			} else {
1780				dma_desc = ep->dwc_ep.desc_addr;
1781				byte_count = 0;
1782				ep->dwc_ep.sent_zlp = 0;
1783
1784				for(i = 0; i < ep->dwc_ep.desc_cnt; ++i) {
1785					desc_sts.d32 = readl(dma_desc);
1786					byte_count += desc_sts.b.bytes;
1787					dma_desc++;
1788				}
1789
1790				if(byte_count == 0) {
1791					ep->dwc_ep.xfer_count = ep->dwc_ep.total_len;
1792					is_last = 1;
1793				} else {
1794					DWC_WARN("Incomplete transfer\n");
1795				}
1796			}
1797		} else {
1798			if (deptsiz.b.xfersize == 0 && deptsiz.b.pktcnt == 0) {
1799				/* 	Check if the whole transfer was completed,
1800				 * 	if no, setup transfer for next portion of data
1801				 */
1802			DWC_DEBUGPL(DBG_PCDV, "%s len=%d  xfersize=%d pktcnt=%d\n",
1803					ep->ep.name, ep->dwc_ep.xfer_len,
1804					deptsiz.b.xfersize, deptsiz.b.pktcnt);
1805				if(ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
1806					dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
1807				} else if(ep->dwc_ep.sent_zlp) {
1808					/*
1809					 * This fragment of code should initiate 0
1810					 * length trasfer in case if it is queued
1811					 * a trasfer with size divisible to EPs max
1812					 * packet size and with usb_request zero field
1813					 * is set, which means that after data is transfered,
1814					 * it is also should be transfered
1815					 * a 0 length packet at the end. For Slave and
1816					 * Buffer DMA modes in this case SW has
1817					 * to initiate 2 transfers one with transfer size,
1818					 * and the second with 0 size. For Desriptor
1819					 * DMA mode SW is able to initiate a transfer,
1820					 * which will handle all the packets including
1821					 * the last  0 legth.
1822					 */
1823					ep->dwc_ep.sent_zlp = 0;
1824					dwc_otg_ep_start_zl_transfer(core_if, &ep->dwc_ep);
1825				} else {
1826					is_last = 1;
1827				}
1828			}
1829			else {
1830				DWC_WARN("Incomplete transfer (%s-%s [siz=%d pkt=%d])\n",
1831						ep->ep.name, (ep->dwc_ep.is_in?"IN":"OUT"),
1832						deptsiz.b.xfersize, deptsiz.b.pktcnt);
1833			}
1834		}
1835	} else {
1836		dwc_otg_dev_out_ep_regs_t *out_ep_regs =
1837				dev_if->out_ep_regs[ep->dwc_ep.num];
1838		desc_sts.d32 = 0;
1839		if(core_if->dma_enable) {
1840			if(core_if->dma_desc_enable) {
1841				dma_desc = ep->dwc_ep.desc_addr;
1842				byte_count = 0;
1843				ep->dwc_ep.sent_zlp = 0;
1844				for(i = 0; i < ep->dwc_ep.desc_cnt; ++i) {
1845					desc_sts.d32 = readl(dma_desc);
1846					byte_count += desc_sts.b.bytes;
1847					dma_desc++;
1848				}
1849
1850				ep->dwc_ep.xfer_count = ep->dwc_ep.total_len
1851						- byte_count + ((4 - (ep->dwc_ep.total_len & 0x3)) & 0x3);
1852				is_last = 1;
1853			} else {
1854				deptsiz.d32 = 0;
1855				deptsiz.d32 = dwc_read_reg32(&out_ep_regs->doeptsiz);
1856
1857				byte_count = (ep->dwc_ep.xfer_len -
1858							 ep->dwc_ep.xfer_count - deptsiz.b.xfersize);
1859				ep->dwc_ep.xfer_buff += byte_count;
1860				ep->dwc_ep.dma_addr += byte_count;
1861				ep->dwc_ep.xfer_count += byte_count;
1862
1863				/* 	Check if the whole transfer was completed,
1864				 * 	if no, setup transfer for next portion of data
1865				 */
1866				if(ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
1867					dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
1868				}
1869				else if(ep->dwc_ep.sent_zlp) {
1870					/*
1871					 * This fragment of code should initiate 0
1872					 * length trasfer in case if it is queued
1873					 * a trasfer with size divisible to EPs max
1874					 * packet size and with usb_request zero field
1875					 * is set, which means that after data is transfered,
1876					 * it is also should be transfered
1877					 * a 0 length packet at the end. For Slave and
1878					 * Buffer DMA modes in this case SW has
1879					 * to initiate 2 transfers one with transfer size,
1880					 * and the second with 0 size. For Desriptor
1881					 * DMA mode SW is able to initiate a transfer,
1882					 * which will handle all the packets including
1883					 * the last  0 legth.
1884					 */
1885					ep->dwc_ep.sent_zlp = 0;
1886					dwc_otg_ep_start_zl_transfer(core_if, &ep->dwc_ep);
1887				} else {
1888					is_last = 1;
1889				}
1890			}
1891		} else {
1892			/* 	Check if the whole transfer was completed,
1893			 * 	if no, setup transfer for next portion of data
1894			 */
1895			if(ep->dwc_ep.xfer_len < ep->dwc_ep.total_len) {
1896				dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
1897			}
1898			else if(ep->dwc_ep.sent_zlp) {
1899				/*
1900				 * This fragment of code should initiate 0
1901				 * length trasfer in case if it is queued
1902				 * a trasfer with size divisible to EPs max
1903				 * packet size and with usb_request zero field
1904				 * is set, which means that after data is transfered,
1905				 * it is also should be transfered
1906				 * a 0 length packet at the end. For Slave and
1907				 * Buffer DMA modes in this case SW has
1908				 * to initiate 2 transfers one with transfer size,
1909				 * and the second with 0 size. For Desriptor
1910				 * DMA mode SW is able to initiate a transfer,
1911				 * which will handle all the packets including
1912				 * the last  0 legth.
1913				 */
1914				ep->dwc_ep.sent_zlp = 0;
1915				dwc_otg_ep_start_zl_transfer(core_if, &ep->dwc_ep);
1916			} else {
1917				is_last = 1;
1918			}
1919		}
1920
1921#ifdef DEBUG
1922
1923		DWC_DEBUGPL(DBG_PCDV, "addr %p,	 %s len=%d cnt=%d xsize=%d pktcnt=%d\n",
1924				&out_ep_regs->doeptsiz, ep->ep.name, ep->dwc_ep.xfer_len,
1925				ep->dwc_ep.xfer_count,
1926				deptsiz.b.xfersize,
1927				deptsiz.b.pktcnt);
1928#endif
1929	}
1930
1931	/* Complete the request */
1932	if (is_last) {
1933		req->req.actual = ep->dwc_ep.xfer_count;
1934
1935		dwc_otg_request_done(ep, req, 0);
1936
1937		ep->dwc_ep.start_xfer_buff = 0;
1938		ep->dwc_ep.xfer_buff = 0;
1939		ep->dwc_ep.xfer_len = 0;
1940
1941		/* If there is a request in the queue start it.*/
1942		start_next_request(ep);
1943	}
1944}
1945
1946
1947#ifdef DWC_EN_ISOC
1948
1949/**
1950 * This function BNA interrupt for Isochronous EPs
1951 *
1952 */
1953static void dwc_otg_pcd_handle_iso_bna(dwc_otg_pcd_ep_t *ep)
1954{
1955	dwc_ep_t		*dwc_ep = &ep->dwc_ep;
1956	volatile uint32_t	*addr;
1957	depctl_data_t		depctl = {.d32 = 0};
1958	dwc_otg_pcd_t		*pcd = ep->pcd;
1959	dwc_otg_dma_desc_t	*dma_desc;
1960	int	i;
1961
1962	dma_desc = dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * (dwc_ep->proc_buf_num);
1963
1964	if(dwc_ep->is_in) {
1965		desc_sts_data_t	sts = {.d32 = 0};
1966		for(i = 0;i < dwc_ep->desc_cnt; ++i, ++dma_desc)
1967		{
1968			sts.d32 = readl(&dma_desc->status);
1969			sts.b_iso_in.bs = BS_HOST_READY;
1970			writel(sts.d32,&dma_desc->status);
1971		}
1972	}
1973	else {
1974		desc_sts_data_t	sts = {.d32 = 0};
1975		for(i = 0;i < dwc_ep->desc_cnt; ++i, ++dma_desc)
1976		{
1977			sts.d32 = readl(&dma_desc->status);
1978			sts.b_iso_out.bs = BS_HOST_READY;
1979			writel(sts.d32,&dma_desc->status);
1980		}
1981	}
1982
1983	if(dwc_ep->is_in == 0){
1984		addr = &GET_CORE_IF(pcd)->dev_if->out_ep_regs[dwc_ep->num]->doepctl;
1985	}
1986	else{
1987		addr = &GET_CORE_IF(pcd)->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
1988	}
1989	depctl.b.epena = 1;
1990	dwc_modify_reg32(addr,depctl.d32,depctl.d32);
1991}
1992
1993/**
1994 * This function sets latest iso packet information(non-PTI mode)
1995 *
1996 * @param core_if Programming view of DWC_otg controller.
1997 * @param ep The EP to start the transfer on.
1998 *
1999 */
2000void set_current_pkt_info(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
2001{
2002	deptsiz_data_t		deptsiz = { .d32 = 0 };
2003	dma_addr_t		dma_addr;
2004	uint32_t		offset;
2005
2006	if(ep->proc_buf_num)
2007		dma_addr = ep->dma_addr1;
2008	else
2009		dma_addr = ep->dma_addr0;
2010
2011
2012	if(ep->is_in) {
2013		deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz);
2014		offset = ep->data_per_frame;
2015	} else {
2016		deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->out_ep_regs[ep->num]->doeptsiz);
2017		offset = ep->data_per_frame + (0x4 & (0x4 - (ep->data_per_frame & 0x3)));
2018	}
2019
2020	if(!deptsiz.b.xfersize) {
2021		ep->pkt_info[ep->cur_pkt].length = ep->data_per_frame;
2022		ep->pkt_info[ep->cur_pkt].offset = ep->cur_pkt_dma_addr - dma_addr;
2023		ep->pkt_info[ep->cur_pkt].status = 0;
2024	} else {
2025		ep->pkt_info[ep->cur_pkt].length = ep->data_per_frame;
2026		ep->pkt_info[ep->cur_pkt].offset = ep->cur_pkt_dma_addr - dma_addr;
2027		ep->pkt_info[ep->cur_pkt].status = -ENODATA;
2028	}
2029	ep->cur_pkt_addr += offset;
2030	ep->cur_pkt_dma_addr += offset;
2031	ep->cur_pkt++;
2032}
2033
2034/**
2035 * This function sets latest iso packet information(DDMA mode)
2036 *
2037 * @param core_if Programming view of DWC_otg controller.
2038 * @param dwc_ep The EP to start the transfer on.
2039 *
2040 */
2041static void set_ddma_iso_pkts_info(dwc_otg_core_if_t *core_if, dwc_ep_t *dwc_ep)
2042{
2043	dwc_otg_dma_desc_t* dma_desc;
2044	desc_sts_data_t sts = {.d32 = 0};
2045	iso_pkt_info_t *iso_packet;
2046	uint32_t data_per_desc;
2047	uint32_t offset;
2048 	int i, j;
2049
2050	iso_packet = dwc_ep->pkt_info;
2051
2052	/** Reinit closed DMA Descriptors*/
2053	/** ISO OUT EP */
2054	if(dwc_ep->is_in == 0) {
2055		dma_desc = dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
2056		offset = 0;
2057
2058		for(i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; i+= dwc_ep->pkt_per_frm)
2059		{
2060			for(j = 0; j < dwc_ep->pkt_per_frm; ++j)
2061			{
2062				data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
2063					dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
2064				data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
2065
2066				sts.d32 = readl(&dma_desc->status);
2067
2068				/* Write status in iso_packet_decsriptor  */
2069				iso_packet->status = sts.b_iso_out.rxsts + (sts.b_iso_out.bs^BS_DMA_DONE);
2070				if(iso_packet->status) {
2071					iso_packet->status = -ENODATA;
2072				}
2073
2074				/* Received data length */
2075				if(!sts.b_iso_out.rxbytes){
2076					iso_packet->length = data_per_desc - sts.b_iso_out.rxbytes;
2077				} else {
2078					iso_packet->length = data_per_desc - sts.b_iso_out.rxbytes +
2079								(4 - dwc_ep->data_per_frame % 4);
2080				}
2081
2082				iso_packet->offset = offset;
2083
2084				offset += data_per_desc;
2085				dma_desc ++;
2086				iso_packet ++;
2087			}
2088		}
2089
2090		for(j = 0; j < dwc_ep->pkt_per_frm - 1; ++j)
2091		{
2092			data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
2093				dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
2094			data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
2095
2096			sts.d32 = readl(&dma_desc->status);
2097
2098			/* Write status in iso_packet_decsriptor  */
2099			iso_packet->status = sts.b_iso_out.rxsts + (sts.b_iso_out.bs^BS_DMA_DONE);
2100			if(iso_packet->status) {
2101				iso_packet->status = -ENODATA;
2102			}
2103
2104			/* Received data length */
2105			iso_packet->length = dwc_ep->data_per_frame - sts.b_iso_out.rxbytes;
2106
2107			iso_packet->offset = offset;
2108
2109			offset += data_per_desc;
2110			iso_packet++;
2111			dma_desc++;
2112		}
2113
2114		sts.d32 = readl(&dma_desc->status);
2115
2116		/* Write status in iso_packet_decsriptor  */
2117		iso_packet->status = sts.b_iso_out.rxsts + (sts.b_iso_out.bs^BS_DMA_DONE);
2118		if(iso_packet->status) {
2119			iso_packet->status = -ENODATA;
2120		}
2121		/* Received data length */
2122		if(!sts.b_iso_out.rxbytes){
2123		iso_packet->length = dwc_ep->data_per_frame - sts.b_iso_out.rxbytes;
2124		} else {
2125			iso_packet->length = dwc_ep->data_per_frame - sts.b_iso_out.rxbytes +
2126							(4 - dwc_ep->data_per_frame % 4);
2127		}
2128
2129		iso_packet->offset = offset;
2130	}
2131	else /** ISO IN EP */
2132	{
2133		dma_desc = dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
2134
2135		for(i = 0; i < dwc_ep->desc_cnt - 1; i++)
2136		{
2137			sts.d32 = readl(&dma_desc->status);
2138
2139			/* Write status in iso packet descriptor */
2140			iso_packet->status = sts.b_iso_in.txsts + (sts.b_iso_in.bs^BS_DMA_DONE);
2141			if(iso_packet->status != 0) {
2142				iso_packet->status = -ENODATA;
2143
2144			}
2145			/* Bytes has been transfered */
2146			iso_packet->length = dwc_ep->data_per_frame - sts.b_iso_in.txbytes;
2147
2148			dma_desc ++;
2149			iso_packet++;
2150		}
2151
2152		sts.d32 = readl(&dma_desc->status);
2153		while(sts.b_iso_in.bs == BS_DMA_BUSY) {
2154			sts.d32 = readl(&dma_desc->status);
2155		}
2156
2157		/* Write status in iso packet descriptor ??? do be done with ERROR codes*/
2158		iso_packet->status = sts.b_iso_in.txsts + (sts.b_iso_in.bs^BS_DMA_DONE);
2159		if(iso_packet->status != 0) {
2160			iso_packet->status = -ENODATA;
2161		}
2162
2163		/* Bytes has been transfered */
2164		iso_packet->length = dwc_ep->data_per_frame - sts.b_iso_in.txbytes;
2165	}
2166}
2167
2168/**
2169 * This function reinitialize DMA Descriptors for Isochronous transfer
2170 *
2171 * @param core_if Programming view of DWC_otg controller.
2172 * @param dwc_ep The EP to start the transfer on.
2173 *
2174 */
2175static void reinit_ddma_iso_xfer(dwc_otg_core_if_t *core_if, dwc_ep_t *dwc_ep)
2176{
2177 	int i, j;
2178	dwc_otg_dma_desc_t* dma_desc;
2179	dma_addr_t dma_ad;
2180	volatile uint32_t	*addr;
2181	desc_sts_data_t sts = { .d32 =0 };
2182	uint32_t data_per_desc;
2183
2184	if(dwc_ep->is_in == 0) {
2185		addr = &core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl;
2186	}
2187	else {
2188		addr = &core_if->dev_if->in_ep_regs[dwc_ep->num]->diepctl;
2189	}
2190
2191
2192	if(dwc_ep->proc_buf_num == 0) {
2193		/** Buffer 0 descriptors setup */
2194		dma_ad = dwc_ep->dma_addr0;
2195	}
2196	else {
2197		/** Buffer 1 descriptors setup */
2198		dma_ad = dwc_ep->dma_addr1;
2199	}
2200
2201
2202	/** Reinit closed DMA Descriptors*/
2203	/** ISO OUT EP */
2204	if(dwc_ep->is_in == 0) {
2205		dma_desc = dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
2206
2207		sts.b_iso_out.bs = BS_HOST_READY;
2208		sts.b_iso_out.rxsts = 0;
2209		sts.b_iso_out.l = 0;
2210		sts.b_iso_out.sp = 0;
2211		sts.b_iso_out.ioc = 0;
2212		sts.b_iso_out.pid = 0;
2213		sts.b_iso_out.framenum = 0;
2214
2215		for(i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; i+= dwc_ep->pkt_per_frm)
2216		{
2217			for(j = 0; j < dwc_ep->pkt_per_frm; ++j)
2218			{
2219				data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
2220					dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
2221				data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
2222				sts.b_iso_out.rxbytes = data_per_desc;
2223				writel((uint32_t)dma_ad, &dma_desc->buf);
2224				writel(sts.d32, &dma_desc->status);
2225
2226				(uint32_t)dma_ad += data_per_desc;
2227				dma_desc ++;
2228			}
2229		}
2230
2231		for(j = 0; j < dwc_ep->pkt_per_frm - 1; ++j)
2232		{
2233
2234			data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
2235				dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
2236			data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
2237			sts.b_iso_out.rxbytes = data_per_desc;
2238
2239			writel((uint32_t)dma_ad, &dma_desc->buf);
2240			writel(sts.d32, &dma_desc->status);
2241
2242			dma_desc++;
2243			(uint32_t)dma_ad += data_per_desc;
2244		}
2245
2246		sts.b_iso_out.ioc = 1;
2247		sts.b_iso_out.l = dwc_ep->proc_buf_num;
2248
2249		data_per_desc = ((j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?
2250			dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;
2251		data_per_desc += (data_per_desc % 4) ? (4 - data_per_desc % 4):0;
2252		sts.b_iso_out.rxbytes = data_per_desc;
2253
2254		writel((uint32_t)dma_ad, &dma_desc->buf);
2255		writel(sts.d32, &dma_desc->status);
2256	}
2257	else /** ISO IN EP */
2258	{
2259		dma_desc = dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * dwc_ep->proc_buf_num;
2260
2261		sts.b_iso_in.bs = BS_HOST_READY;
2262		sts.b_iso_in.txsts = 0;
2263		sts.b_iso_in.sp = 0;
2264		sts.b_iso_in.ioc = 0;
2265		sts.b_iso_in.pid = dwc_ep->pkt_per_frm;
2266		sts.b_iso_in.framenum = dwc_ep->next_frame;
2267		sts.b_iso_in.txbytes = dwc_ep->data_per_frame;
2268		sts.b_iso_in.l = 0;
2269
2270		for(i = 0; i < dwc_ep->desc_cnt - 1; i++)
2271		{
2272			writel((uint32_t)dma_ad, &dma_desc->buf);
2273			writel(sts.d32, &dma_desc->status);
2274
2275			sts.b_iso_in.framenum  += dwc_ep->bInterval;
2276			(uint32_t)dma_ad += dwc_ep->data_per_frame;
2277			dma_desc ++;
2278		}
2279
2280		sts.b_iso_in.ioc = 1;
2281		sts.b_iso_in.l = dwc_ep->proc_buf_num;
2282
2283		writel((uint32_t)dma_ad, &dma_desc->buf);
2284		writel(sts.d32, &dma_desc->status);
2285
2286		dwc_ep->next_frame = sts.b_iso_in.framenum + dwc_ep->bInterval * 1;
2287	}
2288	dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
2289}
2290
2291
2292/**
2293 * This function is to handle Iso EP transfer complete interrupt
2294 * in case Iso out packet was dropped
2295 *
2296 * @param core_if Programming view of DWC_otg controller.
2297 * @param dwc_ep The EP for wihich transfer complete was asserted
2298 *
2299 */
2300static uint32_t handle_iso_out_pkt_dropped(dwc_otg_core_if_t *core_if, dwc_ep_t *dwc_ep)
2301{
2302	uint32_t dma_addr;
2303	uint32_t drp_pkt;
2304	uint32_t drp_pkt_cnt;
2305	deptsiz_data_t deptsiz = { .d32 = 0 };
2306	depctl_data_t depctl  = { .d32 = 0 };
2307	int i;
2308
2309	deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doeptsiz);
2310
2311	drp_pkt = dwc_ep->pkt_cnt - deptsiz.b.pktcnt;
2312	drp_pkt_cnt = dwc_ep->pkt_per_frm - (drp_pkt % dwc_ep->pkt_per_frm);
2313
2314	/* Setting dropped packets status */
2315	for(i = 0; i < drp_pkt_cnt; ++i) {
2316		dwc_ep->pkt_info[drp_pkt].status = -ENODATA;
2317		drp_pkt ++;
2318		deptsiz.b.pktcnt--;
2319	}
2320
2321
2322	if(deptsiz.b.pktcnt > 0) {
2323		deptsiz.b.xfersize = dwc_ep->xfer_len - (dwc_ep->pkt_cnt - deptsiz.b.pktcnt) * dwc_ep->maxpacket;
2324	} else {
2325		deptsiz.b.xfersize = 0;
2326		deptsiz.b.pktcnt = 0;
2327	}
2328
2329	dwc_write_reg32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doeptsiz, deptsiz.d32);
2330
2331	if(deptsiz.b.pktcnt > 0) {
2332		if(dwc_ep->proc_buf_num) {
2333			dma_addr = dwc_ep->dma_addr1 + dwc_ep->xfer_len - deptsiz.b.xfersize;
2334		} else {
2335			dma_addr = dwc_ep->dma_addr0 + dwc_ep->xfer_len - deptsiz.b.xfersize;;
2336		}
2337
2338		dwc_write_reg32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doepdma, dma_addr);
2339
2340		/** Re-enable endpoint, clear nak  */
2341		depctl.d32 = 0;
2342		depctl.b.epena = 1;
2343		depctl.b.cnak = 1;
2344
2345		dwc_modify_reg32(&core_if->dev_if->out_ep_regs[dwc_ep->num]->doepctl,
2346				depctl.d32,depctl.d32);
2347		return 0;
2348	} else {
2349		return 1;
2350	}
2351}
2352
2353/**
2354 * This function sets iso packets information(PTI mode)
2355 *
2356 * @param core_if Programming view of DWC_otg controller.
2357 * @param ep The EP to start the transfer on.
2358 *
2359 */
2360static uint32_t set_iso_pkts_info(dwc_otg_core_if_t *core_if, dwc_ep_t *ep)
2361{
2362 	int i, j;
2363	dma_addr_t dma_ad;
2364	iso_pkt_info_t *packet_info = ep->pkt_info;
2365	uint32_t offset;
2366	uint32_t frame_data;
2367	deptsiz_data_t deptsiz;
2368
2369	if(ep->proc_buf_num == 0) {
2370		/** Buffer 0 descriptors setup */
2371		dma_ad = ep->dma_addr0;
2372	}
2373	else {
2374		/** Buffer 1 descriptors setup */
2375		dma_ad = ep->dma_addr1;
2376	}
2377
2378
2379	if(ep->is_in) {
2380		deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz);
2381	} else {
2382		deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->out_ep_regs[ep->num]->doeptsiz);
2383	}
2384
2385	if(!deptsiz.b.xfersize) {
2386		offset = 0;
2387		for(i = 0; i < ep->pkt_cnt; i += ep->pkt_per_frm)
2388		{
2389			frame_data = ep->data_per_frame;
2390			for(j = 0; j < ep->pkt_per_frm; ++j) {
2391
2392				/* Packet status - is not set as initially
2393				 * it is set to 0 and if packet was sent
2394				 successfully, status field will remain 0*/
2395
2396
2397				/* Bytes has been transfered */
2398				packet_info->length = (ep->maxpacket < frame_data) ?
2399							ep->maxpacket : frame_data;
2400
2401				/* Received packet offset */
2402				packet_info->offset = offset;
2403				offset += packet_info->length;
2404				frame_data -= packet_info->length;
2405
2406				packet_info ++;
2407			}
2408		}
2409		return 1;
2410	} else {
2411		/* This is a workaround for in case of Transfer Complete with
2412		 * PktDrpSts interrupts	merging - in this case Transfer complete
2413		 * interrupt for Isoc Out Endpoint is asserted without PktDrpSts
2414		 * set and with DOEPTSIZ register non zero. Investigations showed,
2415		 * that this happens when Out packet is dropped, but because of
2416		 * interrupts merging during first interrupt handling PktDrpSts
2417		 * bit is cleared and for next merged interrupts it is not reset.
2418		 * In this case SW hadles the interrupt as if PktDrpSts bit is set.
2419		 */
2420		if(ep->is_in) {
2421			return 1;
2422		} else {
2423			return handle_iso_out_pkt_dropped(core_if, ep);
2424		}
2425	}
2426}
2427
2428/**
2429 * This function is to handle Iso EP transfer complete interrupt
2430 *
2431 * @param ep The EP for which transfer complete was asserted
2432 *
2433 */
2434static void complete_iso_ep(dwc_otg_pcd_ep_t *ep)
2435{
2436	dwc_otg_core_if_t *core_if = GET_CORE_IF(ep->pcd);
2437	dwc_ep_t *dwc_ep = &ep->dwc_ep;
2438	uint8_t is_last = 0;
2439
2440	if(core_if->dma_enable) {
2441		if(core_if->dma_desc_enable) {
2442			set_ddma_iso_pkts_info(core_if, dwc_ep);
2443			reinit_ddma_iso_xfer(core_if, dwc_ep);
2444			is_last = 1;
2445		} else {
2446			if(core_if->pti_enh_enable) {
2447				if(set_iso_pkts_info(core_if, dwc_ep)) {
2448					dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
2449					dwc_otg_iso_ep_start_buf_transfer(core_if, dwc_ep);
2450					is_last = 1;
2451				}
2452			} else {
2453				set_current_pkt_info(core_if, dwc_ep);
2454				if(dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
2455					is_last = 1;
2456					dwc_ep->cur_pkt = 0;
2457					dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
2458					if(dwc_ep->proc_buf_num) {
2459						dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff1;
2460						dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr1;
2461					} else {
2462						dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff0;
2463						dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr0;
2464					}
2465
2466				}
2467				dwc_otg_iso_ep_start_frm_transfer(core_if, dwc_ep);
2468			}
2469		}
2470	} else {
2471		set_current_pkt_info(core_if, dwc_ep);
2472		if(dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
2473			is_last = 1;
2474			dwc_ep->cur_pkt = 0;
2475			dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
2476			if(dwc_ep->proc_buf_num) {
2477				dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff1;
2478				dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr1;
2479			} else {
2480				dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff0;
2481				dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr0;
2482			}
2483
2484		}
2485		dwc_otg_iso_ep_start_frm_transfer(core_if, dwc_ep);
2486	}
2487	if(is_last)
2488		dwc_otg_iso_buffer_done(ep, ep->iso_req);
2489}
2490
2491#endif  //DWC_EN_ISOC
2492
2493
2494/**
2495 * This function handles EP0 Control transfers.
2496 *
2497 * The state of the control tranfers are tracked in
2498 * <code>ep0state</code>.
2499 */
2500static void handle_ep0(dwc_otg_pcd_t *pcd)
2501{
2502	dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
2503	dwc_otg_pcd_ep_t *ep0 = &pcd->ep0;
2504	desc_sts_data_t desc_sts;
2505	deptsiz0_data_t deptsiz;
2506	uint32_t byte_count;
2507
2508#ifdef DEBUG_EP0
2509	DWC_DEBUGPL(DBG_PCDV, "%s()\n", __func__);
2510	print_ep0_state(pcd);
2511#endif
2512
2513	switch (pcd->ep0state) {
2514	case EP0_DISCONNECT:
2515		break;
2516
2517	case EP0_IDLE:
2518		pcd->request_config = 0;
2519
2520		pcd_setup(pcd);
2521		break;
2522
2523	case EP0_IN_DATA_PHASE:
2524#ifdef DEBUG_EP0
2525		DWC_DEBUGPL(DBG_PCD, "DATA_IN EP%d-%s: type=%d, mps=%d\n",
2526				ep0->dwc_ep.num, (ep0->dwc_ep.is_in ?"IN":"OUT"),
2527				ep0->dwc_ep.type, ep0->dwc_ep.maxpacket);
2528#endif
2529
2530		if (core_if->dma_enable != 0) {
2531			/*
2532			 * For EP0 we can only program 1 packet at a time so we
2533			 * need to do the make calculations after each complete.
2534			 * Call write_packet to make the calculations, as in
2535			 * slave mode, and use those values to determine if we
2536			 * can complete.
2537			 */
2538			if(core_if->dma_desc_enable == 0) {
2539				deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->in_ep_regs[0]->dieptsiz);
2540				byte_count = ep0->dwc_ep.xfer_len - deptsiz.b.xfersize;
2541			}
2542			else {
2543				desc_sts.d32 = readl(core_if->dev_if->in_desc_addr);
2544				byte_count = ep0->dwc_ep.xfer_len - desc_sts.b.bytes;
2545			}
2546			ep0->dwc_ep.xfer_count += byte_count;
2547			ep0->dwc_ep.xfer_buff += byte_count;
2548			ep0->dwc_ep.dma_addr += byte_count;
2549		}
2550		if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len) {
2551			dwc_otg_ep0_continue_transfer (GET_CORE_IF(pcd), &ep0->dwc_ep);
2552			DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
2553		}
2554		else if(ep0->dwc_ep.sent_zlp) {
2555			dwc_otg_ep0_continue_transfer (GET_CORE_IF(pcd), &ep0->dwc_ep);
2556			ep0->dwc_ep.sent_zlp = 0;
2557			DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
2558		}
2559		else {
2560			ep0_complete_request(ep0);
2561			DWC_DEBUGPL(DBG_PCD, "COMPLETE TRANSFER\n");
2562		}
2563		break;
2564	case EP0_OUT_DATA_PHASE:
2565#ifdef DEBUG_EP0
2566		DWC_DEBUGPL(DBG_PCD, "DATA_OUT EP%d-%s: type=%d, mps=%d\n",
2567				ep0->dwc_ep.num, (ep0->dwc_ep.is_in ?"IN":"OUT"),
2568				ep0->dwc_ep.type, ep0->dwc_ep.maxpacket);
2569#endif
2570		if (core_if->dma_enable != 0) {
2571			if(core_if->dma_desc_enable == 0) {
2572				deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->out_ep_regs[0]->doeptsiz);
2573				byte_count = ep0->dwc_ep.maxpacket - deptsiz.b.xfersize;
2574			}
2575			else {
2576				desc_sts.d32 = readl(core_if->dev_if->out_desc_addr);
2577				byte_count = ep0->dwc_ep.maxpacket - desc_sts.b.bytes;
2578			}
2579			ep0->dwc_ep.xfer_count += byte_count;
2580			ep0->dwc_ep.xfer_buff += byte_count;
2581			ep0->dwc_ep.dma_addr += byte_count;
2582		}
2583		if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len) {
2584			dwc_otg_ep0_continue_transfer (GET_CORE_IF(pcd), &ep0->dwc_ep);
2585			DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
2586		}
2587		else if(ep0->dwc_ep.sent_zlp) {
2588			dwc_otg_ep0_continue_transfer (GET_CORE_IF(pcd), &ep0->dwc_ep);
2589			ep0->dwc_ep.sent_zlp = 0;
2590			DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");
2591	}
2592		else {
2593			ep0_complete_request(ep0);
2594			DWC_DEBUGPL(DBG_PCD, "COMPLETE TRANSFER\n");
2595		}
2596		break;
2597
2598
2599	case EP0_IN_STATUS_PHASE:
2600	case EP0_OUT_STATUS_PHASE:
2601		DWC_DEBUGPL(DBG_PCD, "CASE: EP0_STATUS\n");
2602				ep0_complete_request(ep0);
2603				pcd->ep0state = EP0_IDLE;
2604				ep0->stopped = 1;
2605				ep0->dwc_ep.is_in = 0;	/* OUT for next SETUP */
2606
2607		/* Prepare for more SETUP Packets */
2608		if(core_if->dma_enable) {
2609			ep0_out_start(core_if, pcd);
2610		}
2611		break;
2612
2613	case EP0_STALL:
2614		DWC_ERROR("EP0 STALLed, should not get here pcd_setup()\n");
2615		break;
2616	}
2617#ifdef DEBUG_EP0
2618	print_ep0_state(pcd);
2619#endif
2620}
2621
2622
2623/**
2624 * Restart transfer
2625 */
2626static void restart_transfer(dwc_otg_pcd_t *pcd, const uint32_t epnum)
2627{
2628	dwc_otg_core_if_t *core_if;
2629	dwc_otg_dev_if_t *dev_if;
2630	deptsiz_data_t dieptsiz = {.d32=0};
2631	dwc_otg_pcd_ep_t *ep;
2632
2633	ep = get_in_ep(pcd, epnum);
2634
2635#ifdef DWC_EN_ISOC
2636	if(ep->dwc_ep.type == DWC_OTG_EP_TYPE_ISOC) {
2637		return;
2638	}
2639#endif /* DWC_EN_ISOC  */
2640
2641	core_if = GET_CORE_IF(pcd);
2642	dev_if = core_if->dev_if;
2643
2644	dieptsiz.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dieptsiz);
2645
2646	DWC_DEBUGPL(DBG_PCD,"xfer_buff=%p xfer_count=%0x xfer_len=%0x"
2647			" stopped=%d\n", ep->dwc_ep.xfer_buff,
2648			ep->dwc_ep.xfer_count, ep->dwc_ep.xfer_len ,
2649			ep->stopped);
2650	/*
2651	 * If xfersize is 0 and pktcnt in not 0, resend the last packet.
2652	 */
2653	if (dieptsiz.b.pktcnt && dieptsiz.b.xfersize == 0 &&
2654		 ep->dwc_ep.start_xfer_buff != 0) {
2655		if (ep->dwc_ep.total_len <= ep->dwc_ep.maxpacket) {
2656			ep->dwc_ep.xfer_count = 0;
2657			ep->dwc_ep.xfer_buff = ep->dwc_ep.start_xfer_buff;
2658			ep->dwc_ep.xfer_len = ep->dwc_ep.xfer_count;
2659		}
2660		else {
2661			ep->dwc_ep.xfer_count -= ep->dwc_ep.maxpacket;
2662			/* convert packet size to dwords. */
2663			ep->dwc_ep.xfer_buff -= ep->dwc_ep.maxpacket;
2664			ep->dwc_ep.xfer_len = ep->dwc_ep.xfer_count;
2665		}
2666		ep->stopped = 0;
2667		DWC_DEBUGPL(DBG_PCD,"xfer_buff=%p xfer_count=%0x "
2668					"xfer_len=%0x stopped=%d\n",
2669					ep->dwc_ep.xfer_buff,
2670					ep->dwc_ep.xfer_count, ep->dwc_ep.xfer_len ,
2671					ep->stopped
2672					);
2673		if (epnum == 0) {
2674			dwc_otg_ep0_start_transfer(core_if, &ep->dwc_ep);
2675		}
2676		else {
2677			dwc_otg_ep_start_transfer(core_if, &ep->dwc_ep);
2678		}
2679	}
2680}
2681
2682
2683/**
2684 * handle the IN EP disable interrupt.
2685 */
2686static inline void handle_in_ep_disable_intr(dwc_otg_pcd_t *pcd,
2687						 const uint32_t epnum)
2688{
2689	dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
2690	dwc_otg_dev_if_t *dev_if = core_if->dev_if;
2691	deptsiz_data_t dieptsiz = {.d32=0};
2692	dctl_data_t dctl = {.d32=0};
2693	dwc_otg_pcd_ep_t *ep;
2694	dwc_ep_t *dwc_ep;
2695
2696	ep = get_in_ep(pcd, epnum);
2697	dwc_ep = &ep->dwc_ep;
2698
2699	if(dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
2700		dwc_otg_flush_tx_fifo(core_if, dwc_ep->tx_fifo_num);
2701		return;
2702	}
2703
2704	DWC_DEBUGPL(DBG_PCD,"diepctl%d=%0x\n", epnum,
2705			dwc_read_reg32(&dev_if->in_ep_regs[epnum]->diepctl));
2706	dieptsiz.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->dieptsiz);
2707
2708	DWC_DEBUGPL(DBG_ANY, "pktcnt=%d size=%d\n",
2709			dieptsiz.b.pktcnt,
2710			dieptsiz.b.xfersize);
2711
2712	if (ep->stopped) {
2713		/* Flush the Tx FIFO */
2714		dwc_otg_flush_tx_fifo(core_if, dwc_ep->tx_fifo_num);
2715		/* Clear the Global IN NP NAK */
2716		dctl.d32 = 0;
2717		dctl.b.cgnpinnak = 1;
2718		dwc_modify_reg32(&dev_if->dev_global_regs->dctl,
2719					 dctl.d32, 0);
2720		/* Restart the transaction */
2721		if (dieptsiz.b.pktcnt != 0 ||
2722			dieptsiz.b.xfersize != 0) {
2723			restart_transfer(pcd, epnum);
2724		}
2725	}
2726	else {
2727		/* Restart the transaction */
2728		if (dieptsiz.b.pktcnt != 0 ||
2729			dieptsiz.b.xfersize != 0) {
2730			restart_transfer(pcd, epnum);
2731		}
2732		DWC_DEBUGPL(DBG_ANY, "STOPPED!!!\n");
2733	}
2734}
2735
2736/**
2737 * Handler for the IN EP timeout handshake interrupt.
2738 */
2739static inline void handle_in_ep_timeout_intr(dwc_otg_pcd_t *pcd,
2740						const uint32_t epnum)
2741{
2742	dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
2743	dwc_otg_dev_if_t *dev_if = core_if->dev_if;
2744
2745#ifdef DEBUG
2746	deptsiz_data_t dieptsiz = {.d32=0};
2747	uint32_t num = 0;
2748#endif
2749	dctl_data_t dctl = {.d32=0};
2750	dwc_otg_pcd_ep_t *ep;
2751
2752	gintmsk_data_t intr_mask = {.d32 = 0};
2753
2754	ep = get_in_ep(pcd, epnum);
2755
2756	/* Disable the NP Tx Fifo Empty Interrrupt */
2757	if (!core_if->dma_enable) {
2758		intr_mask.b.nptxfempty = 1;
2759		dwc_modify_reg32(&core_if->core_global_regs->gintmsk, intr_mask.d32, 0);
2760	}
2761	/** @todo NGS Check EP type.
2762	 * Implement for Periodic EPs */
2763	/*
2764	 * Non-periodic EP
2765	 */
2766	/* Enable the Global IN NAK Effective Interrupt */
2767	intr_mask.b.ginnakeff = 1;
2768	dwc_modify_reg32(&core_if->core_global_regs->gintmsk,
2769					  0, intr_mask.d32);
2770
2771	/* Set Global IN NAK */
2772	dctl.b.sgnpinnak = 1;
2773	dwc_modify_reg32(&dev_if->dev_global_regs->dctl,
2774					 dctl.d32, dctl.d32);
2775
2776	ep->stopped = 1;
2777
2778#ifdef DEBUG
2779	dieptsiz.d32 = dwc_read_reg32(&dev_if->in_ep_regs[num]->dieptsiz);
2780	DWC_DEBUGPL(DBG_ANY, "pktcnt=%d size=%d\n",
2781			dieptsiz.b.pktcnt,
2782			dieptsiz.b.xfersize);
2783#endif
2784
2785#ifdef DISABLE_PERIODIC_EP
2786	/*
2787	 * Set the NAK bit for this EP to
2788	 * start the disable process.
2789	 */
2790	diepctl.d32 = 0;
2791	diepctl.b.snak = 1;
2792	dwc_modify_reg32(&dev_if->in_ep_regs[num]->diepctl, diepctl.d32, diepctl.d32);
2793	ep->disabling = 1;
2794	ep->stopped = 1;
2795#endif
2796}
2797
2798/**
2799 * Handler for the IN EP NAK interrupt.
2800 */
2801static inline int32_t handle_in_ep_nak_intr(dwc_otg_pcd_t *pcd,
2802						const uint32_t epnum)
2803{
2804        /** @todo implement ISR */
2805        dwc_otg_core_if_t* core_if;
2806	diepmsk_data_t intr_mask = { .d32 = 0};
2807
2808	DWC_PRINT("INTERRUPT Handler not implemented for %s\n", "IN EP NAK");
2809	core_if = GET_CORE_IF(pcd);
2810	intr_mask.b.nak = 1;
2811
2812	if(core_if->multiproc_int_enable) {
2813		dwc_modify_reg32(&core_if->dev_if->dev_global_regs->diepeachintmsk[epnum],
2814					  intr_mask.d32, 0);
2815	} else {
2816		dwc_modify_reg32(&core_if->dev_if->dev_global_regs->diepmsk,
2817					  intr_mask.d32, 0);
2818	}
2819
2820	return 1;
2821}
2822
2823/**
2824 * Handler for the OUT EP Babble interrupt.
2825 */
2826static inline int32_t handle_out_ep_babble_intr(dwc_otg_pcd_t *pcd,
2827						const uint32_t epnum)
2828{
2829        /** @todo implement ISR */
2830        dwc_otg_core_if_t* core_if;
2831	doepmsk_data_t intr_mask = { .d32 = 0};
2832
2833 	DWC_PRINT("INTERRUPT Handler not implemented for %s\n", "OUT EP Babble");
2834	core_if = GET_CORE_IF(pcd);
2835	intr_mask.b.babble = 1;
2836
2837	if(core_if->multiproc_int_enable) {
2838		dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepeachintmsk[epnum],
2839					  intr_mask.d32, 0);
2840	} else {
2841		dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepmsk,
2842					  intr_mask.d32, 0);
2843	}
2844
2845	return 1;
2846}
2847
2848/**
2849 * Handler for the OUT EP NAK interrupt.
2850 */
2851static inline int32_t handle_out_ep_nak_intr(dwc_otg_pcd_t *pcd,
2852						const uint32_t epnum)
2853{
2854        /** @todo implement ISR */
2855        dwc_otg_core_if_t* core_if;
2856	doepmsk_data_t intr_mask = { .d32 = 0};
2857
2858	DWC_PRINT("INTERRUPT Handler not implemented for %s\n", "OUT EP NAK");
2859	core_if = GET_CORE_IF(pcd);
2860	intr_mask.b.nak = 1;
2861
2862	if(core_if->multiproc_int_enable) {
2863		dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepeachintmsk[epnum],
2864					  intr_mask.d32, 0);
2865	} else {
2866		dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepmsk,
2867					  intr_mask.d32, 0);
2868	}
2869
2870	return 1;
2871}
2872
2873/**
2874 * Handler for the OUT EP NYET interrupt.
2875 */
2876static inline int32_t handle_out_ep_nyet_intr(dwc_otg_pcd_t *pcd,
2877						const uint32_t epnum)
2878{
2879        /** @todo implement ISR */
2880        dwc_otg_core_if_t* core_if;
2881	doepmsk_data_t intr_mask = { .d32 = 0};
2882
2883	DWC_PRINT("INTERRUPT Handler not implemented for %s\n", "OUT EP NYET");
2884	core_if = GET_CORE_IF(pcd);
2885	intr_mask.b.nyet = 1;
2886
2887	if(core_if->multiproc_int_enable) {
2888		dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepeachintmsk[epnum],
2889					  intr_mask.d32, 0);
2890	} else {
2891		dwc_modify_reg32(&core_if->dev_if->dev_global_regs->doepmsk,
2892					  intr_mask.d32, 0);
2893	}
2894
2895	return 1;
2896}
2897
2898/**
2899 * This interrupt indicates that an IN EP has a pending Interrupt.
2900 * The sequence for handling the IN EP interrupt is shown below:
2901 * -#	Read the Device All Endpoint Interrupt register
2902 * -#	Repeat the following for each IN EP interrupt bit set (from
2903 *		LSB to MSB).
2904 * -#	Read the Device Endpoint Interrupt (DIEPINTn) register
2905 * -#	If "Transfer Complete" call the request complete function
2906 * -#	If "Endpoint Disabled" complete the EP disable procedure.
2907 * -#	If "AHB Error Interrupt" log error
2908 * -#	If "Time-out Handshake" log error
2909 * -#	If "IN Token Received when TxFIFO Empty" write packet to Tx
2910 *		FIFO.
2911 * -#	If "IN Token EP Mismatch" (disable, this is handled by EP
2912 *		Mismatch Interrupt)
2913 */
2914static int32_t dwc_otg_pcd_handle_in_ep_intr(dwc_otg_pcd_t *pcd)
2915{
2916#define CLEAR_IN_EP_INTR(__core_if,__epnum,__intr) \
2917do { \
2918		diepint_data_t diepint = {.d32=0}; \
2919		diepint.b.__intr = 1; \
2920		dwc_write_reg32(&__core_if->dev_if->in_ep_regs[__epnum]->diepint, \
2921		diepint.d32); \
2922} while (0)
2923
2924	dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
2925	dwc_otg_dev_if_t *dev_if = core_if->dev_if;
2926	diepint_data_t diepint = {.d32=0};
2927	dctl_data_t dctl = {.d32=0};
2928	depctl_data_t depctl = {.d32=0};
2929	uint32_t ep_intr;
2930	uint32_t epnum = 0;
2931	dwc_otg_pcd_ep_t *ep;
2932	dwc_ep_t *dwc_ep;
2933	gintmsk_data_t intr_mask = {.d32 = 0};
2934
2935
2936
2937	DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, pcd);
2938
2939	/* Read in the device interrupt bits */
2940	ep_intr = dwc_otg_read_dev_all_in_ep_intr(core_if);
2941
2942	/* Service the Device IN interrupts for each endpoint */
2943	while(ep_intr) {
2944		if (ep_intr&0x1) {
2945			uint32_t empty_msk;
2946			/* Get EP pointer */
2947			ep = get_in_ep(pcd, epnum);
2948			dwc_ep = &ep->dwc_ep;
2949
2950			depctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->diepctl);
2951			empty_msk = dwc_read_reg32(&dev_if->dev_global_regs->dtknqr4_fifoemptymsk);
2952
2953			DWC_DEBUGPL(DBG_PCDV,
2954					"IN EP INTERRUPT - %d\nepmty_msk - %8x  diepctl - %8x\n",
2955					epnum,
2956					empty_msk,
2957					depctl.d32);
2958
2959			DWC_DEBUGPL(DBG_PCD,
2960					"EP%d-%s: type=%d, mps=%d\n",
2961					dwc_ep->num, (dwc_ep->is_in ?"IN":"OUT"),
2962					dwc_ep->type, dwc_ep->maxpacket);
2963
2964			diepint.d32 = dwc_otg_read_dev_in_ep_intr(core_if, dwc_ep);
2965
2966			DWC_DEBUGPL(DBG_PCDV, "EP %d Interrupt Register - 0x%x\n", epnum, diepint.d32);
2967			/* Transfer complete */
2968			if (diepint.b.xfercompl) {
2969				/* Disable the NP Tx FIFO Empty
2970				 * Interrrupt */
2971					if(core_if->en_multiple_tx_fifo == 0) {
2972					intr_mask.b.nptxfempty = 1;
2973					dwc_modify_reg32(&core_if->core_global_regs->gintmsk, intr_mask.d32, 0);
2974				}
2975				else {
2976					/* Disable the Tx FIFO Empty Interrupt for this EP */
2977					uint32_t fifoemptymsk = 0x1 << dwc_ep->num;
2978					dwc_modify_reg32(&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
2979					fifoemptymsk, 0);
2980				}
2981				/* Clear the bit in DIEPINTn for this interrupt */
2982				CLEAR_IN_EP_INTR(core_if,epnum,xfercompl);
2983
2984				/* Complete the transfer */
2985				if (epnum == 0) {
2986					handle_ep0(pcd);
2987				}
2988#ifdef DWC_EN_ISOC
2989				else if(dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
2990					if(!ep->stopped)
2991						complete_iso_ep(ep);
2992				}
2993#endif //DWC_EN_ISOC
2994				else {
2995
2996					complete_ep(ep);
2997				}
2998			}
2999			/* Endpoint disable	 */
3000			if (diepint.b.epdisabled) {
3001				DWC_DEBUGPL(DBG_ANY,"EP%d IN disabled\n", epnum);
3002				handle_in_ep_disable_intr(pcd, epnum);
3003
3004				/* Clear the bit in DIEPINTn for this interrupt */
3005				CLEAR_IN_EP_INTR(core_if,epnum,epdisabled);
3006			}
3007			/* AHB Error */
3008			if (diepint.b.ahberr) {
3009				DWC_DEBUGPL(DBG_ANY,"EP%d IN AHB Error\n", epnum);
3010				/* Clear the bit in DIEPINTn for this interrupt */
3011				CLEAR_IN_EP_INTR(core_if,epnum,ahberr);
3012			}
3013			/* TimeOUT Handshake (non-ISOC IN EPs) */
3014			if (diepint.b.timeout) {
3015				DWC_DEBUGPL(DBG_ANY,"EP%d IN Time-out\n", epnum);
3016				handle_in_ep_timeout_intr(pcd, epnum);
3017
3018				CLEAR_IN_EP_INTR(core_if,epnum,timeout);
3019			}
3020			/** IN Token received with TxF Empty */
3021			if (diepint.b.intktxfemp) {
3022				DWC_DEBUGPL(DBG_ANY,"EP%d IN TKN TxFifo Empty\n",
3023								epnum);
3024				if (!ep->stopped && epnum != 0) {
3025
3026					diepmsk_data_t diepmsk = { .d32 = 0};
3027					diepmsk.b.intktxfemp = 1;
3028
3029					if(core_if->multiproc_int_enable) {
3030						dwc_modify_reg32(&dev_if->dev_global_regs->diepeachintmsk[epnum],
3031							diepmsk.d32, 0);
3032					} else {
3033						dwc_modify_reg32(&dev_if->dev_global_regs->diepmsk, diepmsk.d32, 0);
3034					}
3035					start_next_request(ep);
3036				}
3037				else if(core_if->dma_desc_enable && epnum == 0 &&
3038						pcd->ep0state == EP0_OUT_STATUS_PHASE) {
3039					// EP0 IN set STALL
3040					depctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[epnum]->diepctl);
3041
3042					/* set the disable and stall bits */
3043					if (depctl.b.epena) {
3044						depctl.b.epdis = 1;
3045					}
3046					depctl.b.stall = 1;
3047					dwc_write_reg32(&dev_if->in_ep_regs[epnum]->diepctl, depctl.d32);
3048				}
3049				CLEAR_IN_EP_INTR(core_if,epnum,intktxfemp);
3050			}
3051			/** IN Token Received with EP mismatch */
3052			if (diepint.b.intknepmis) {
3053				DWC_DEBUGPL(DBG_ANY,"EP%d IN TKN EP Mismatch\n", epnum);
3054				CLEAR_IN_EP_INTR(core_if,epnum,intknepmis);
3055			}
3056			/** IN Endpoint NAK Effective */
3057			if (diepint.b.inepnakeff) {
3058				DWC_DEBUGPL(DBG_ANY,"EP%d IN EP NAK Effective\n", epnum);
3059				/* Periodic EP */
3060				if (ep->disabling) {
3061					depctl.d32 = 0;
3062					depctl.b.snak = 1;
3063					depctl.b.epdis = 1;
3064					dwc_modify_reg32(&dev_if->in_ep_regs[epnum]->diepctl, depctl.d32, depctl.d32);
3065				}
3066				CLEAR_IN_EP_INTR(core_if,epnum,inepnakeff);
3067
3068			}
3069
3070			/** IN EP Tx FIFO Empty Intr */
3071			if (diepint.b.emptyintr) {
3072				DWC_DEBUGPL(DBG_ANY,"EP%d Tx FIFO Empty Intr \n", epnum);
3073				write_empty_tx_fifo(pcd, epnum);
3074
3075				CLEAR_IN_EP_INTR(core_if,epnum,emptyintr);
3076
3077			}
3078
3079			/** IN EP BNA Intr */
3080			if (diepint.b.bna) {
3081				CLEAR_IN_EP_INTR(core_if,epnum,bna);
3082				if(core_if->dma_desc_enable) {
3083#ifdef DWC_EN_ISOC
3084					if(dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
3085						/*
3086						 * This checking is performed to prevent first "false" BNA
3087						 * handling occuring right after reconnect
3088						 */
3089						if(dwc_ep->next_frame != 0xffffffff)
3090							dwc_otg_pcd_handle_iso_bna(ep);
3091					}
3092					else
3093#endif //DWC_EN_ISOC
3094					{
3095						dctl.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dctl);
3096
3097						/* If Global Continue on BNA is disabled - disable EP */
3098						if(!dctl.b.gcontbna) 						{
3099							depctl.d32 = 0;
3100							depctl.b.snak = 1;
3101							depctl.b.epdis = 1;
3102							dwc_modify_reg32(&dev_if->in_ep_regs[epnum]->diepctl, depctl.d32, depctl.d32);
3103						} else {
3104							start_next_request(ep);
3105						}
3106					}
3107				}
3108			}
3109			/* NAK Interrutp */
3110			if (diepint.b.nak) {
3111				DWC_DEBUGPL(DBG_ANY,"EP%d IN NAK Interrupt\n", epnum);
3112				handle_in_ep_nak_intr(pcd, epnum);
3113
3114				CLEAR_IN_EP_INTR(core_if,epnum,nak);
3115			}
3116		}
3117		epnum++;
3118		ep_intr >>=1;
3119	}
3120
3121	return 1;
3122#undef CLEAR_IN_EP_INTR
3123}
3124
3125/**
3126 * This interrupt indicates that an OUT EP has a pending Interrupt.
3127 * The sequence for handling the OUT EP interrupt is shown below:
3128 * -#	Read the Device All Endpoint Interrupt register
3129 * -#	Repeat the following for each OUT EP interrupt bit set (from
3130 *		LSB to MSB).
3131 * -#	Read the Device Endpoint Interrupt (DOEPINTn) register
3132 * -#	If "Transfer Complete" call the request complete function
3133 * -#	If "Endpoint Disabled" complete the EP disable procedure.
3134 * -#	If "AHB Error Interrupt" log error
3135 * -#	If "Setup Phase Done" process Setup Packet (See Standard USB
3136 *		Command Processing)
3137 */
3138static int32_t dwc_otg_pcd_handle_out_ep_intr(dwc_otg_pcd_t *pcd)
3139{
3140#define CLEAR_OUT_EP_INTR(__core_if,__epnum,__intr) \
3141do { \
3142		doepint_data_t doepint = {.d32=0}; \
3143		doepint.b.__intr = 1; \
3144		dwc_write_reg32(&__core_if->dev_if->out_ep_regs[__epnum]->doepint, \
3145		doepint.d32); \
3146} while (0)
3147
3148	dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
3149	dwc_otg_dev_if_t *dev_if = core_if->dev_if;
3150	uint32_t ep_intr;
3151	doepint_data_t doepint = {.d32=0};
3152	dctl_data_t dctl = {.d32=0};
3153	depctl_data_t doepctl = {.d32=0};
3154	uint32_t epnum = 0;
3155	dwc_otg_pcd_ep_t *ep;
3156	dwc_ep_t *dwc_ep;
3157
3158	DWC_DEBUGPL(DBG_PCDV, "%s()\n", __func__);
3159
3160	/* Read in the device interrupt bits */
3161	ep_intr = dwc_otg_read_dev_all_out_ep_intr(core_if);
3162
3163	while(ep_intr) {
3164		if (ep_intr&0x1) {
3165			/* Get EP pointer */
3166			ep = get_out_ep(pcd, epnum);
3167			dwc_ep = &ep->dwc_ep;
3168
3169#ifdef VERBOSE
3170			DWC_DEBUGPL(DBG_PCDV,
3171					"EP%d-%s: type=%d, mps=%d\n",
3172					dwc_ep->num, (dwc_ep->is_in ?"IN":"OUT"),
3173					dwc_ep->type, dwc_ep->maxpacket);
3174#endif
3175			doepint.d32 = dwc_otg_read_dev_out_ep_intr(core_if, dwc_ep);
3176
3177			/* Transfer complete */
3178			if (doepint.b.xfercompl) {
3179
3180				if (epnum == 0) {
3181					/* Clear the bit in DOEPINTn for this interrupt */
3182					CLEAR_OUT_EP_INTR(core_if,epnum,xfercompl);
3183					if(core_if->dma_desc_enable == 0 || pcd->ep0state != EP0_IDLE)
3184						handle_ep0(pcd);
3185#ifdef DWC_EN_ISOC
3186				} else if(dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
3187					if (doepint.b.pktdrpsts == 0) {
3188						/* Clear the bit in DOEPINTn for this interrupt */
3189						CLEAR_OUT_EP_INTR(core_if,epnum,xfercompl);
3190						complete_iso_ep(ep);
3191					} else {
3192
3193						doepint_data_t doepint = {.d32=0};
3194						doepint.b.xfercompl = 1;
3195						doepint.b.pktdrpsts = 1;
3196						dwc_write_reg32(&core_if->dev_if->out_ep_regs[epnum]->doepint,
3197							doepint.d32);
3198						if(handle_iso_out_pkt_dropped(core_if,dwc_ep)) {
3199							complete_iso_ep(ep);
3200						}
3201					}
3202#endif //DWC_EN_ISOC
3203				} else {
3204					/* Clear the bit in DOEPINTn for this interrupt */
3205					CLEAR_OUT_EP_INTR(core_if,epnum,xfercompl);
3206					complete_ep(ep);
3207				}
3208
3209			}
3210
3211			/* Endpoint disable	 */
3212			if (doepint.b.epdisabled) {
3213
3214				/* Clear the bit in DOEPINTn for this interrupt */
3215				CLEAR_OUT_EP_INTR(core_if,epnum,epdisabled);
3216			}
3217			/* AHB Error */
3218			if (doepint.b.ahberr) {
3219				DWC_DEBUGPL(DBG_PCD,"EP%d OUT AHB Error\n", epnum);
3220				DWC_DEBUGPL(DBG_PCD,"EP DMA REG	 %d \n", core_if->dev_if->out_ep_regs[epnum]->doepdma);
3221				CLEAR_OUT_EP_INTR(core_if,epnum,ahberr);
3222			}
3223			/* Setup Phase Done (contorl EPs) */
3224			if (doepint.b.setup) {
3225#ifdef DEBUG_EP0
3226				DWC_DEBUGPL(DBG_PCD,"EP%d SETUP Done\n",
3227							epnum);
3228#endif
3229				CLEAR_OUT_EP_INTR(core_if,epnum,setup);
3230
3231				handle_ep0(pcd);
3232			}
3233
3234			/** OUT EP BNA Intr */
3235			if (doepint.b.bna) {
3236				CLEAR_OUT_EP_INTR(core_if,epnum,bna);
3237				if(core_if->dma_desc_enable) {
3238#ifdef DWC_EN_ISOC
3239					if(dwc_ep->type == DWC_OTG_EP_TYPE_ISOC) {
3240						/*
3241						 * This checking is performed to prevent first "false" BNA
3242						 * handling occuring right after reconnect
3243						 */
3244						if(dwc_ep->next_frame != 0xffffffff)
3245							dwc_otg_pcd_handle_iso_bna(ep);
3246					}
3247					else
3248#endif //DWC_EN_ISOC
3249					{
3250						dctl.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dctl);
3251
3252						/* If Global Continue on BNA is disabled - disable EP*/
3253						if(!dctl.b.gcontbna) {
3254							doepctl.d32 = 0;
3255							doepctl.b.snak = 1;
3256							doepctl.b.epdis = 1;
3257							dwc_modify_reg32(&dev_if->out_ep_regs[epnum]->doepctl, doepctl.d32, doepctl.d32);
3258						} else {
3259							start_next_request(ep);
3260						}
3261					}
3262				}
3263			}
3264			if (doepint.b.stsphsercvd) {
3265				CLEAR_OUT_EP_INTR(core_if,epnum,stsphsercvd);
3266				if(core_if->dma_desc_enable) {
3267					do_setup_in_status_phase(pcd);
3268				}
3269			}
3270			/* Babble Interrutp */
3271			if (doepint.b.babble) {
3272				DWC_DEBUGPL(DBG_ANY,"EP%d OUT Babble\n", epnum);
3273				handle_out_ep_babble_intr(pcd, epnum);
3274
3275				CLEAR_OUT_EP_INTR(core_if,epnum,babble);
3276			}
3277			/* NAK Interrutp */
3278			if (doepint.b.nak) {
3279				DWC_DEBUGPL(DBG_ANY,"EP%d OUT NAK\n", epnum);
3280				handle_out_ep_nak_intr(pcd, epnum);
3281
3282				CLEAR_OUT_EP_INTR(core_if,epnum,nak);
3283			}
3284			/* NYET Interrutp */
3285			if (doepint.b.nyet) {
3286				DWC_DEBUGPL(DBG_ANY,"EP%d OUT NYET\n", epnum);
3287				handle_out_ep_nyet_intr(pcd, epnum);
3288
3289				CLEAR_OUT_EP_INTR(core_if,epnum,nyet);
3290			}
3291		}
3292
3293		epnum++;
3294		ep_intr >>=1;
3295	}
3296
3297	return 1;
3298
3299#undef CLEAR_OUT_EP_INTR
3300}
3301
3302
3303/**
3304 * Incomplete ISO IN Transfer Interrupt.
3305 * This interrupt indicates one of the following conditions occurred
3306 * while transmitting an ISOC transaction.
3307 * - Corrupted IN Token for ISOC EP.
3308 * - Packet not complete in FIFO.
3309 * The follow actions will be taken:
3310 *	-#	Determine the EP
3311 *	-#	Set incomplete flag in dwc_ep structure
3312 *	-#	Disable EP; when "Endpoint Disabled" interrupt is received
3313 *		Flush FIFO
3314 */
3315int32_t dwc_otg_pcd_handle_incomplete_isoc_in_intr(dwc_otg_pcd_t *pcd)
3316{
3317	gintsts_data_t 		gintsts;
3318
3319
3320#ifdef DWC_EN_ISOC
3321	dwc_otg_dev_if_t 	*dev_if;
3322	deptsiz_data_t 		deptsiz = { .d32 = 0};
3323	depctl_data_t		depctl = { .d32 = 0};
3324	dsts_data_t		dsts = { .d32 = 0};
3325	dwc_ep_t		*dwc_ep;
3326	int i;
3327
3328	dev_if = GET_CORE_IF(pcd)->dev_if;
3329
3330	for(i = 1; i <= dev_if->num_in_eps; ++i) {
3331		dwc_ep = &pcd->in_ep[i].dwc_ep;
3332		if(dwc_ep->active &&
3333			dwc_ep->type == USB_ENDPOINT_XFER_ISOC)
3334		{
3335			deptsiz.d32 = dwc_read_reg32(&dev_if->in_ep_regs[i]->dieptsiz);
3336			depctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[i]->diepctl);
3337
3338			if(depctl.b.epdis && deptsiz.d32) {
3339				set_current_pkt_info(GET_CORE_IF(pcd), dwc_ep);
3340				if(dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
3341					dwc_ep->cur_pkt = 0;
3342					dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
3343
3344					if(dwc_ep->proc_buf_num) {
3345						dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff1;
3346						dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr1;
3347					} else {
3348						dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff0;
3349						dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr0;
3350					}
3351
3352				}
3353
3354				dsts.d32 = dwc_read_reg32(&GET_CORE_IF(pcd)->dev_if->dev_global_regs->dsts);
3355				dwc_ep->next_frame = dsts.b.soffn;
3356
3357				dwc_otg_iso_ep_start_frm_transfer(GET_CORE_IF(pcd), dwc_ep);
3358			}
3359		}
3360	}
3361
3362#else
3363        gintmsk_data_t intr_mask = { .d32 = 0};
3364        DWC_PRINT("INTERRUPT Handler not implemented for %s\n",
3365                          "IN ISOC Incomplete");
3366
3367        intr_mask.b.incomplisoin = 1;
3368        dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
3369                                intr_mask.d32, 0);
3370#endif //DWC_EN_ISOC
3371
3372	/* Clear interrupt */
3373	gintsts.d32 = 0;
3374	gintsts.b.incomplisoin = 1;
3375	dwc_write_reg32 (&GET_CORE_IF(pcd)->core_global_regs->gintsts,
3376				gintsts.d32);
3377
3378	return 1;
3379}
3380
3381/**
3382 * Incomplete ISO OUT Transfer Interrupt.
3383 *
3384 * This interrupt indicates that the core has dropped an ISO OUT
3385 * packet.	The following conditions can be the cause:
3386 * - FIFO Full, the entire packet would not fit in the FIFO.
3387 * - CRC Error
3388 * - Corrupted Token
3389 * The follow actions will be taken:
3390 *	-#	Determine the EP
3391 *	-#	Set incomplete flag in dwc_ep structure
3392 *	-#	Read any data from the FIFO
3393 *	-#	Disable EP.	 when "Endpoint Disabled" interrupt is received
3394 *		re-enable EP.
3395 */
3396int32_t dwc_otg_pcd_handle_incomplete_isoc_out_intr(dwc_otg_pcd_t *pcd)
3397{
3398	/* @todo implement ISR */
3399	gintsts_data_t gintsts;
3400
3401#ifdef DWC_EN_ISOC
3402	dwc_otg_dev_if_t 	*dev_if;
3403	deptsiz_data_t 		deptsiz = { .d32 = 0};
3404	depctl_data_t		depctl = { .d32 = 0};
3405	dsts_data_t		dsts = { .d32 = 0};
3406	dwc_ep_t		*dwc_ep;
3407	int i;
3408
3409	dev_if = GET_CORE_IF(pcd)->dev_if;
3410
3411	for(i = 1; i <= dev_if->num_out_eps; ++i) {
3412		dwc_ep = &pcd->in_ep[i].dwc_ep;
3413		if(pcd->out_ep[i].dwc_ep.active &&
3414			pcd->out_ep[i].dwc_ep.type == USB_ENDPOINT_XFER_ISOC)
3415		{
3416			deptsiz.d32 = dwc_read_reg32(&dev_if->out_ep_regs[i]->doeptsiz);
3417			depctl.d32 = dwc_read_reg32(&dev_if->out_ep_regs[i]->doepctl);
3418
3419			if(depctl.b.epdis && deptsiz.d32) {
3420				set_current_pkt_info(GET_CORE_IF(pcd), &pcd->out_ep[i].dwc_ep);
3421				if(dwc_ep->cur_pkt >= dwc_ep->pkt_cnt) {
3422					dwc_ep->cur_pkt = 0;
3423					dwc_ep->proc_buf_num = (dwc_ep->proc_buf_num ^ 1) & 0x1;
3424
3425					if(dwc_ep->proc_buf_num) {
3426						dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff1;
3427						dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr1;
3428					} else {
3429						dwc_ep->cur_pkt_addr = dwc_ep->xfer_buff0;
3430						dwc_ep->cur_pkt_dma_addr = dwc_ep->dma_addr0;
3431					}
3432
3433				}
3434
3435				dsts.d32 = dwc_read_reg32(&GET_CORE_IF(pcd)->dev_if->dev_global_regs->dsts);
3436				dwc_ep->next_frame = dsts.b.soffn;
3437
3438				dwc_otg_iso_ep_start_frm_transfer(GET_CORE_IF(pcd), dwc_ep);
3439			}
3440		}
3441	}
3442#else
3443        /** @todo implement ISR */
3444        gintmsk_data_t intr_mask = { .d32 = 0};
3445
3446        DWC_PRINT("INTERRUPT Handler not implemented for %s\n",
3447                          "OUT ISOC Incomplete");
3448
3449        intr_mask.b.incomplisoout = 1;
3450        dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
3451                                intr_mask.d32, 0);
3452
3453#endif // DWC_EN_ISOC
3454
3455	/* Clear interrupt */
3456	gintsts.d32 = 0;
3457	gintsts.b.incomplisoout = 1;
3458	dwc_write_reg32 (&GET_CORE_IF(pcd)->core_global_regs->gintsts,
3459				gintsts.d32);
3460
3461	return 1;
3462}
3463
3464/**
3465 * This function handles the Global IN NAK Effective interrupt.
3466 *
3467 */
3468int32_t dwc_otg_pcd_handle_in_nak_effective(dwc_otg_pcd_t *pcd)
3469{
3470	dwc_otg_dev_if_t *dev_if = GET_CORE_IF(pcd)->dev_if;
3471	depctl_data_t diepctl = { .d32 = 0};
3472	depctl_data_t diepctl_rd = { .d32 = 0};
3473	gintmsk_data_t intr_mask = { .d32 = 0};
3474	gintsts_data_t gintsts;
3475	int i;
3476
3477	DWC_DEBUGPL(DBG_PCD, "Global IN NAK Effective\n");
3478
3479	/* Disable all active IN EPs */
3480	diepctl.b.epdis = 1;
3481	diepctl.b.snak = 1;
3482
3483	for (i=0; i <= dev_if->num_in_eps; i++)
3484	{
3485		diepctl_rd.d32 = dwc_read_reg32(&dev_if->in_ep_regs[i]->diepctl);
3486		if (diepctl_rd.b.epena) {
3487			dwc_write_reg32(&dev_if->in_ep_regs[i]->diepctl,
3488						diepctl.d32);
3489		}
3490	}
3491	/* Disable the Global IN NAK Effective Interrupt */
3492	intr_mask.b.ginnakeff = 1;
3493	dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
3494					  intr_mask.d32, 0);
3495
3496	/* Clear interrupt */
3497	gintsts.d32 = 0;
3498	gintsts.b.ginnakeff = 1;
3499	dwc_write_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintsts,
3500						 gintsts.d32);
3501
3502	return 1;
3503}
3504
3505/**
3506 * OUT NAK Effective.
3507 *
3508 */
3509int32_t dwc_otg_pcd_handle_out_nak_effective(dwc_otg_pcd_t *pcd)
3510{
3511	gintmsk_data_t intr_mask = { .d32 = 0};
3512	gintsts_data_t gintsts;
3513
3514	DWC_PRINT("INTERRUPT Handler not implemented for %s\n",
3515			  "Global IN NAK Effective\n");
3516	/* Disable the Global IN NAK Effective Interrupt */
3517	intr_mask.b.goutnakeff = 1;
3518	dwc_modify_reg32(&GET_CORE_IF(pcd)->core_global_regs->gintmsk,
3519					  intr_mask.d32, 0);
3520
3521	/* Clear interrupt */
3522	gintsts.d32 = 0;
3523	gintsts.b.goutnakeff = 1;
3524	dwc_write_reg32 (&GET_CORE_IF(pcd)->core_global_regs->gintsts,
3525						 gintsts.d32);
3526
3527	return 1;
3528}
3529
3530
3531/**
3532 * PCD interrupt handler.
3533 *
3534 * The PCD handles the device interrupts.  Many conditions can cause a
3535 * device interrupt. When an interrupt occurs, the device interrupt
3536 * service routine determines the cause of the interrupt and
3537 * dispatches handling to the appropriate function. These interrupt
3538 * handling functions are described below.
3539 *
3540 * All interrupt registers are processed from LSB to MSB.
3541 *
3542 */
3543int32_t dwc_otg_pcd_handle_intr(dwc_otg_pcd_t *pcd)
3544{
3545	dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
3546#ifdef VERBOSE
3547	dwc_otg_core_global_regs_t *global_regs =
3548			core_if->core_global_regs;
3549#endif
3550	gintsts_data_t gintr_status;
3551	int32_t retval = 0;
3552
3553
3554#ifdef VERBOSE
3555	DWC_DEBUGPL(DBG_ANY, "%s() gintsts=%08x	 gintmsk=%08x\n",
3556				__func__,
3557				dwc_read_reg32(&global_regs->gintsts),
3558				dwc_read_reg32(&global_regs->gintmsk));
3559#endif
3560
3561	if (dwc_otg_is_device_mode(core_if)) {
3562		SPIN_LOCK(&pcd->lock);
3563#ifdef VERBOSE
3564		DWC_DEBUGPL(DBG_PCDV, "%s() gintsts=%08x  gintmsk=%08x\n",
3565						__func__,
3566						dwc_read_reg32(&global_regs->gintsts),
3567						dwc_read_reg32(&global_regs->gintmsk));
3568#endif
3569
3570		gintr_status.d32 = dwc_otg_read_core_intr(core_if);
3571
3572/*
3573		if (!gintr_status.d32) {
3574			SPIN_UNLOCK(&pcd->lock);
3575			return 0;
3576		}
3577*/
3578		DWC_DEBUGPL(DBG_PCDV, "%s: gintsts&gintmsk=%08x\n",
3579					__func__, gintr_status.d32);
3580
3581		if (gintr_status.b.sofintr) {
3582			retval |= dwc_otg_pcd_handle_sof_intr(pcd);
3583		}
3584		if (gintr_status.b.rxstsqlvl) {
3585			retval |= dwc_otg_pcd_handle_rx_status_q_level_intr(pcd);
3586		}
3587		if (gintr_status.b.nptxfempty) {
3588			retval |= dwc_otg_pcd_handle_np_tx_fifo_empty_intr(pcd);
3589		}
3590		if (gintr_status.b.ginnakeff) {
3591			retval |= dwc_otg_pcd_handle_in_nak_effective(pcd);
3592		}
3593		if (gintr_status.b.goutnakeff) {
3594			retval |= dwc_otg_pcd_handle_out_nak_effective(pcd);
3595		}
3596		if (gintr_status.b.i2cintr) {
3597			retval |= dwc_otg_pcd_handle_i2c_intr(pcd);
3598		}
3599		if (gintr_status.b.erlysuspend) {
3600			retval |= dwc_otg_pcd_handle_early_suspend_intr(pcd);
3601		}
3602		if (gintr_status.b.usbreset) {
3603			retval |= dwc_otg_pcd_handle_usb_reset_intr(pcd);
3604		}
3605		if (gintr_status.b.enumdone) {
3606			retval |= dwc_otg_pcd_handle_enum_done_intr(pcd);
3607		}
3608		if (gintr_status.b.isooutdrop) {
3609			retval |= dwc_otg_pcd_handle_isoc_out_packet_dropped_intr(pcd);
3610		}
3611		if (gintr_status.b.eopframe) {
3612			retval |= dwc_otg_pcd_handle_end_periodic_frame_intr(pcd);
3613		}
3614		if (gintr_status.b.epmismatch) {
3615			retval |= dwc_otg_pcd_handle_ep_mismatch_intr(core_if);
3616		}
3617		if (gintr_status.b.inepint) {
3618			if(!core_if->multiproc_int_enable) {
3619				retval |= dwc_otg_pcd_handle_in_ep_intr(pcd);
3620			}
3621		}
3622		if (gintr_status.b.outepintr) {
3623			if(!core_if->multiproc_int_enable) {
3624				retval |= dwc_otg_pcd_handle_out_ep_intr(pcd);
3625			}
3626		}
3627		if (gintr_status.b.incomplisoin) {
3628			retval |= dwc_otg_pcd_handle_incomplete_isoc_in_intr(pcd);
3629		}
3630		if (gintr_status.b.incomplisoout) {
3631			retval |= dwc_otg_pcd_handle_incomplete_isoc_out_intr(pcd);
3632		}
3633
3634		/* In MPI mode De vice Endpoints intterrupts are asserted
3635		 * without setting outepintr and inepint bits set, so these
3636		 * Interrupt handlers are called without checking these bit-fields
3637		 */
3638		if(core_if->multiproc_int_enable) {
3639			retval |= dwc_otg_pcd_handle_in_ep_intr(pcd);
3640			retval |= dwc_otg_pcd_handle_out_ep_intr(pcd);
3641		}
3642#ifdef VERBOSE
3643		DWC_DEBUGPL(DBG_PCDV, "%s() gintsts=%0x\n", __func__,
3644						dwc_read_reg32(&global_regs->gintsts));
3645#endif
3646		SPIN_UNLOCK(&pcd->lock);
3647	}
3648
3649	S3C2410X_CLEAR_EINTPEND();
3650
3651	return retval;
3652}
3653
3654#endif /* DWC_HOST_ONLY */
3655