]> CyberLeo.Net >> Repos - FreeBSD/releng/8.2.git/blob - sys/contrib/octeon-sdk/cvmx-usb.c
Copy stable/8 to releng/8.2 in preparation for FreeBSD-8.2 release.
[FreeBSD/releng/8.2.git] / sys / contrib / octeon-sdk / cvmx-usb.c
1 /***********************license start***************
2  *  Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights
3  *  reserved.
4  *
5  *
6  *  Redistribution and use in source and binary forms, with or without
7  *  modification, are permitted provided that the following conditions are
8  *  met:
9  *
10  *      * Redistributions of source code must retain the above copyright
11  *        notice, this list of conditions and the following disclaimer.
12  *
13  *      * Redistributions in binary form must reproduce the above
14  *        copyright notice, this list of conditions and the following
15  *        disclaimer in the documentation and/or other materials provided
16  *        with the distribution.
17  *
18  *      * Neither the name of Cavium Networks nor the names of
19  *        its contributors may be used to endorse or promote products
20  *        derived from this software without specific prior written
21  *        permission.
22  *
23  *  TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
24  *  AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS
25  *  OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
26  *  RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
27  *  REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
28  *  DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
29  *  OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
30  *  PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET
31  *  POSSESSION OR CORRESPONDENCE TO DESCRIPTION.  THE ENTIRE RISK ARISING OUT
32  *  OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
33  *
34  *
35  *  For any questions regarding licensing please contact marketing@caviumnetworks.com
36  *
37  ***********************license end**************************************/
38
39 /**
40  * @file
41  *
42  * "cvmx-usb.c" defines a set of low level USB functions to help
43  * developers create Octeon USB drivers for various operating
44  * systems. These functions provide a generic API to the Octeon
45  * USB blocks, hiding the internal hardware specific
46  * operations.
47  *
48  * <hr>$Revision: 32636 $<hr>
49  */
50 #include "cvmx.h"
51 #include "cvmx-sysinfo.h"
52 #include "cvmx-usb.h"
53 #include "cvmx-helper.h"
54 #include "cvmx-helper-board.h"
55 #include "cvmx-csr-db.h"
56 #include "cvmx-swap.h"
57
58 #define MAX_RETRIES         3   /* Maximum number of times to retry failed transactions */
59 #define MAX_PIPES           32  /* Maximum number of pipes that can be open at once */
60 #define MAX_TRANSACTIONS    256 /* Maximum number of outstanding transactions across all pipes */
61 #define MAX_CHANNELS        8   /* Maximum number of hardware channels supported by the USB block */
62 #define MAX_USB_ADDRESS     127 /* The highest valid USB device address */
63 #define MAX_USB_ENDPOINT    15  /* The highest valid USB endpoint number */
64 #define MAX_USB_HUB_PORT    15  /* The highest valid port number on a hub */
65 #define ALLOW_CSR_DECODES   0   /* CSR decoding when CVMX_USB_INITIALIZE_FLAGS_DEBUG_CSRS is set
66                                     enlarges the code a lot. This define overrides the ability to do CSR
67                                     decoding since it isn't necessary 99% of the time. Change this to a
68                                     one if you need CSR decoding */
69
70 /* These defines disable the normal read and write csr. This is so I can add
71     extra debug stuff to the usb specific version and I won't use the normal
72     version by mistake */
73 #define cvmx_read_csr use_cvmx_usb_read_csr64_instead_of_cvmx_read_csr
74 #define cvmx_write_csr use_cvmx_usb_write_csr64_instead_of_cvmx_write_csr
75
76 typedef enum
77 {
78     __CVMX_USB_TRANSACTION_FLAGS_IN_USE = 1<<16,
79 } cvmx_usb_transaction_flags_t;
80
81 /**
82  * Logical transactions may take numerous low level
83  * transactions, especially when splits are concerned. This
84  * enum represents all of the possible stages a transaction can
85  * be in. Note that split completes are always even. This is so
86  * the NAK handler can backup to the previous low level
87  * transaction with a simple clearing of bit 0.
88  */
89 typedef enum
90 {
91     CVMX_USB_STAGE_NON_CONTROL,
92     CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE,
93     CVMX_USB_STAGE_SETUP,
94     CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE,
95     CVMX_USB_STAGE_DATA,
96     CVMX_USB_STAGE_DATA_SPLIT_COMPLETE,
97     CVMX_USB_STAGE_STATUS,
98     CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE,
99 } cvmx_usb_stage_t;
100
101 /**
102  * This structure describes each pending USB transaction
103  * regardless of type. These are linked together to form a list
104  * of pending requests for a pipe.
105  */
106 typedef struct cvmx_usb_transaction
107 {
108     struct cvmx_usb_transaction *prev;  /**< Transaction before this one in the pipe */
109     struct cvmx_usb_transaction *next;  /**< Transaction after this one in the pipe */
110     cvmx_usb_transfer_t type;           /**< Type of transaction, duplicated of the pipe */
111     cvmx_usb_transaction_flags_t flags; /**< State flags for this transaction */
112     uint64_t buffer;                    /**< User's physical buffer address to read/write */
113     int buffer_length;                  /**< Size of the user's buffer in bytes */
114     uint64_t control_header;            /**< For control transactions, physical address of the 8 byte standard header */
115     int iso_start_frame;                /**< For ISO transactions, the starting frame number */
116     int iso_number_packets;             /**< For ISO transactions, the number of packets in the request */
117     cvmx_usb_iso_packet_t *iso_packets; /**< For ISO transactions, the sub packets in the request */
118     int xfersize;
119     int pktcnt;
120     int retries;
121     int actual_bytes;                   /**< Actual bytes transfer for this transaction */
122     cvmx_usb_stage_t stage;             /**< For control transactions, the current stage */
123     cvmx_usb_callback_func_t callback;  /**< User's callback function when complete */
124     void *callback_data;                /**< User's data */
125 } cvmx_usb_transaction_t;
126
127 /**
128  * A pipe represents a virtual connection between Octeon and some
129  * USB device. It contains a list of pending request to the device.
130  */
131 typedef struct cvmx_usb_pipe
132 {
133     struct cvmx_usb_pipe *prev;         /**< Pipe before this one in the list */
134     struct cvmx_usb_pipe *next;         /**< Pipe after this one in the list */
135     cvmx_usb_transaction_t *head;       /**< The first pending transaction */
136     cvmx_usb_transaction_t *tail;       /**< The last pending transaction */
137     uint64_t interval;                  /**< For periodic pipes, the interval between packets in cycles */
138     uint64_t next_tx_cycle;             /**< The next cycle this pipe is allowed to transmit on */
139     cvmx_usb_pipe_flags_t flags;        /**< State flags for this pipe */
140     cvmx_usb_speed_t device_speed;      /**< Speed of device connected to this pipe */
141     cvmx_usb_transfer_t transfer_type;  /**< Type of transaction supported by this pipe */
142     cvmx_usb_direction_t transfer_dir;  /**< IN or OUT. Ignored for Control */
143     int multi_count;                    /**< Max packet in a row for the device */
144     uint16_t max_packet;                /**< The device's maximum packet size in bytes */
145     uint8_t device_addr;                /**< USB device address at other end of pipe */
146     uint8_t endpoint_num;               /**< USB endpoint number at other end of pipe */
147     uint8_t hub_device_addr;            /**< Hub address this device is connected to */
148     uint8_t hub_port;                   /**< Hub port this device is connected to */
149     uint8_t pid_toggle;                 /**< This toggles between 0/1 on every packet send to track the data pid needed */
150     uint8_t channel;                    /**< Hardware DMA channel for this pipe */
151     int8_t  split_sc_frame;             /**< The low order bits of the frame number the split complete should be sent on */
152 } cvmx_usb_pipe_t;
153
154 typedef struct
155 {
156     cvmx_usb_pipe_t *head;              /**< Head of the list, or NULL if empty */
157     cvmx_usb_pipe_t *tail;              /**< Tail if the list, or NULL if empty */
158 } cvmx_usb_pipe_list_t;
159
160 /**
161  * The state of the USB block is stored in this structure
162  */
163 typedef struct
164 {
165     int init_flags;                     /**< Flags passed to initialize */
166     int index;                          /**< Which USB block this is for */
167     int idle_hardware_channels;         /**< Bit set for every idle hardware channel */
168     int active_transactions;            /**< Number of active transactions across all pipes */
169     cvmx_usbcx_hprt_t usbcx_hprt;       /**< Stored port status so we don't need to read a CSR to determine splits */
170     cvmx_usb_pipe_t *pipe_for_channel[MAX_CHANNELS];    /**< Map channels to pipes */
171     cvmx_usb_transaction_t *free_transaction_head;      /**< List of free transactions head */
172     cvmx_usb_transaction_t *free_transaction_tail;      /**< List of free transactions tail */
173     cvmx_usb_pipe_t pipe[MAX_PIPES];                    /**< Storage for pipes */
174     cvmx_usb_transaction_t transaction[MAX_TRANSACTIONS];       /**< Storage for transactions */
175     cvmx_usb_callback_func_t callback[__CVMX_USB_CALLBACK_END]; /**< User global callbacks */
176     void *callback_data[__CVMX_USB_CALLBACK_END];               /**< User data for each callback */
177     int indent;                         /**< Used by debug output to indent functions */
178     cvmx_usb_port_status_t port_status; /**< Last port status used for change notification */
179     cvmx_usb_pipe_list_t free_pipes;    /**< List of all pipes that are currently closed */
180     cvmx_usb_pipe_list_t idle_pipes;    /**< List of open pipes that have no transactions */
181     cvmx_usb_pipe_list_t active_pipes[4]; /**< Active pipes indexed by transfer type */
182 } cvmx_usb_internal_state_t;
183
184 /* This macro logs out whenever a function is called if debugging is on */
185 #define CVMX_USB_LOG_CALLED() \
186     if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CALLS)) \
187         cvmx_dprintf("%*s%s: called\n", 2*usb->indent++, "", __FUNCTION__);
188
189 /* This macro logs out each function parameter if debugging is on */
190 #define CVMX_USB_LOG_PARAM(format, param) \
191     if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CALLS)) \
192         cvmx_dprintf("%*s%s: param %s = " format "\n", 2*usb->indent, "", __FUNCTION__, #param, param);
193
194 /* This macro logs out when a function returns a value */
195 #define CVMX_USB_RETURN(v)                                              \
196     do {                                                                \
197         __typeof(v) r = v;                                              \
198         if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CALLS))    \
199             cvmx_dprintf("%*s%s: returned %s(%d)\n", 2*--usb->indent, "", __FUNCTION__, #v, r); \
200         return r;                                                       \
201     } while (0);
202
203 /* This macro logs out when a function doesn't return a value */
204 #define CVMX_USB_RETURN_NOTHING()                                       \
205     do {                                                                \
206         if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CALLS))    \
207             cvmx_dprintf("%*s%s: returned\n", 2*--usb->indent, "", __FUNCTION__); \
208         return;                                                         \
209     } while (0);
210
211 /* This macro spins on a field waiting for it to reach a value */
212 #define CVMX_WAIT_FOR_FIELD32(address, type, field, op, value, timeout_usec)\
213     ({int result;                                                       \
214     do {                                                                \
215         uint64_t done = cvmx_get_cycle() + (uint64_t)timeout_usec *     \
216                            cvmx_sysinfo_get()->cpu_clock_hz / 1000000;  \
217         type c;                                                         \
218         while (1)                                                       \
219         {                                                               \
220             c.u32 = __cvmx_usb_read_csr32(usb, address);                \
221             if (c.s.field op (value)) {                                 \
222                 result = 0;                                             \
223                 break;                                                  \
224             } else if (cvmx_get_cycle() > done) {                       \
225                 result = -1;                                            \
226                 break;                                                  \
227             } else                                                      \
228                 cvmx_wait(100);                                         \
229         }                                                               \
230     } while (0);                                                        \
231     result;})
232
233 /* This macro logically sets a single field in a CSR. It does the sequence
234     read, modify, and write */
235 #define USB_SET_FIELD32(address, type, field, value)\
236     do {                                            \
237         type c;                                     \
238         c.u32 = __cvmx_usb_read_csr32(usb, address);\
239         c.s.field = value;                          \
240         __cvmx_usb_write_csr32(usb, address, c.u32);\
241     } while (0)
242
243
244 /**
245  * @INTERNAL
246  * Read a USB 32bit CSR. It performs the necessary address swizzle
247  * for 32bit CSRs and logs the value in a readable format if
248  * debugging is on.
249  *
250  * @param usb     USB block this access is for
251  * @param address 64bit address to read
252  *
253  * @return Result of the read
254  */
255 static inline uint32_t __cvmx_usb_read_csr32(cvmx_usb_internal_state_t *usb,
256                                              uint64_t address)
257 {
258     uint32_t result = cvmx_read64_uint32(address ^ 4);
259 #if ALLOW_CSR_DECODES
260     if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CSRS))
261     {
262         cvmx_dprintf("Read: ");
263         cvmx_csr_db_decode(cvmx_get_proc_id(), address, result);
264     }
265 #endif
266     return result;
267 }
268
269
270 /**
271  * @INTERNAL
272  * Write a USB 32bit CSR. It performs the necessary address
273  * swizzle for 32bit CSRs and logs the value in a readable format
274  * if debugging is on.
275  *
276  * @param usb     USB block this access is for
277  * @param address 64bit address to write
278  * @param value   Value to write
279  */
280 static inline void __cvmx_usb_write_csr32(cvmx_usb_internal_state_t *usb,
281                                           uint64_t address, uint32_t value)
282 {
283 #if ALLOW_CSR_DECODES
284     if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CSRS))
285     {
286         cvmx_dprintf("Write: ");
287         cvmx_csr_db_decode(cvmx_get_proc_id(), address, value);
288     }
289 #endif
290     cvmx_write64_uint32(address ^ 4, value);
291 }
292
293
294 /**
295  * @INTERNAL
296  * Read a USB 64bit CSR. It logs the value in a readable format if
297  * debugging is on.
298  *
299  * @param usb     USB block this access is for
300  * @param address 64bit address to read
301  *
302  * @return Result of the read
303  */
304 static inline uint64_t __cvmx_usb_read_csr64(cvmx_usb_internal_state_t *usb,
305                                              uint64_t address)
306 {
307     uint64_t result = cvmx_read64_uint64(address);
308 #if ALLOW_CSR_DECODES
309     if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CSRS))
310     {
311         cvmx_dprintf("Read: ");
312         cvmx_csr_db_decode(cvmx_get_proc_id(), address, result);
313     }
314 #endif
315     return result;
316 }
317
318
319 /**
320  * @INTERNAL
321  * Write a USB 64bit CSR. It logs the value in a readable format
322  * if debugging is on.
323  *
324  * @param usb     USB block this access is for
325  * @param address 64bit address to write
326  * @param value   Value to write
327  */
328 static inline void __cvmx_usb_write_csr64(cvmx_usb_internal_state_t *usb,
329                                           uint64_t address, uint64_t value)
330 {
331 #if ALLOW_CSR_DECODES
332     if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CSRS))
333     {
334         cvmx_dprintf("Write: ");
335         cvmx_csr_db_decode(cvmx_get_proc_id(), address, value);
336     }
337 #endif
338     cvmx_write64_uint64(address, value);
339 }
340
341
342 /**
343  * @INTERNAL
344  * Uitility function to convert complete codes into strings
345  *
346  * @param complete_code
347  *               Code to convert
348  *
349  * @return Human readable string
350  */
351 static const char *__cvmx_usb_complete_to_string(cvmx_usb_complete_t complete_code)
352 {
353     switch (complete_code)
354     {
355         case CVMX_USB_COMPLETE_SUCCESS: return "SUCCESS";
356         case CVMX_USB_COMPLETE_SHORT:   return "SHORT";
357         case CVMX_USB_COMPLETE_CANCEL:  return "CANCEL";
358         case CVMX_USB_COMPLETE_ERROR:   return "ERROR";
359         case CVMX_USB_COMPLETE_STALL:   return "STALL";
360         case CVMX_USB_COMPLETE_XACTERR: return "XACTERR";
361         case CVMX_USB_COMPLETE_DATATGLERR: return "DATATGLERR";
362         case CVMX_USB_COMPLETE_BABBLEERR: return "BABBLEERR";
363         case CVMX_USB_COMPLETE_FRAMEERR: return "FRAMEERR";
364     }
365     return "Update __cvmx_usb_complete_to_string";
366 }
367
368
369 /**
370  * @INTERNAL
371  * Return non zero if this pipe connects to a non HIGH speed
372  * device through a high speed hub.
373  *
374  * @param usb    USB block this access is for
375  * @param pipe   Pipe to check
376  *
377  * @return Non zero if we need to do split transactions
378  */
379 static inline int __cvmx_usb_pipe_needs_split(cvmx_usb_internal_state_t *usb, cvmx_usb_pipe_t *pipe)
380 {
381     return ((pipe->device_speed != CVMX_USB_SPEED_HIGH) && (usb->usbcx_hprt.s.prtspd == CVMX_USB_SPEED_HIGH));
382 }
383
384
385 /**
386  * @INTERNAL
387  * Trivial utility function to return the correct PID for a pipe
388  *
389  * @param pipe   pipe to check
390  *
391  * @return PID for pipe
392  */
393 static inline int __cvmx_usb_get_data_pid(cvmx_usb_pipe_t *pipe)
394 {
395     if (pipe->pid_toggle)
396         return 2; /* Data1 */
397     else
398         return 0; /* Data0 */
399 }
400
401
402 /**
403  * Return the number of USB ports supported by this Octeon
404  * chip. If the chip doesn't support USB, or is not supported
405  * by this API, a zero will be returned. Most Octeon chips
406  * support one usb port, but some support two ports.
407  * cvmx_usb_initialize() must be called on independent
408  * cvmx_usb_state_t structures.
409  *
410  * This utilizes cvmx_helper_board_usb_get_num_ports()
411  * to get any board specific variatons.
412  *
413  * @return Number of port, zero if usb isn't supported
414  */
415 int cvmx_usb_get_num_ports(void)
416 {
417     int arch_ports = 0;
418
419     if (OCTEON_IS_MODEL(OCTEON_CN52XX))
420         arch_ports = 2;
421     else if (OCTEON_IS_MODEL(OCTEON_CN31XX))
422         arch_ports = 0; /* This chip has USB but it doesn't support DMA */
423     else if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX))
424         arch_ports = 0;
425     else
426         arch_ports = 1;
427
428     return __cvmx_helper_board_usb_get_num_ports(arch_ports);
429 }
430
431
432 /**
433  * @INTERNAL
434  * Allocate a usb transaction for use
435  *
436  * @param usb    USB device state populated by
437  *               cvmx_usb_initialize().
438  *
439  * @return Transaction or NULL
440  */
441 static inline cvmx_usb_transaction_t *__cvmx_usb_alloc_transaction(cvmx_usb_internal_state_t *usb)
442 {
443     cvmx_usb_transaction_t *t;
444     t = usb->free_transaction_head;
445     if (t)
446     {
447         usb->free_transaction_head = t->next;
448         if (!usb->free_transaction_head)
449             usb->free_transaction_tail = NULL;
450     }
451     else if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO))
452         cvmx_dprintf("%s: Failed to allocate a transaction\n", __FUNCTION__);
453     if (t)
454     {
455         memset(t, 0, sizeof(*t));
456         t->flags = __CVMX_USB_TRANSACTION_FLAGS_IN_USE;
457     }
458     return t;
459 }
460
461
462 /**
463  * @INTERNAL
464  * Free a usb transaction
465  *
466  * @param usb    USB device state populated by
467  *               cvmx_usb_initialize().
468  * @param transaction
469  *               Transaction to free
470  */
471 static inline void __cvmx_usb_free_transaction(cvmx_usb_internal_state_t *usb,
472                                         cvmx_usb_transaction_t *transaction)
473 {
474     transaction->flags = 0;
475     transaction->prev = NULL;
476     transaction->next = NULL;
477     if (usb->free_transaction_tail)
478         usb->free_transaction_tail->next = transaction;
479     else
480         usb->free_transaction_head = transaction;
481     usb->free_transaction_tail = transaction;
482 }
483
484
485 /**
486  * @INTERNAL
487  * Add a pipe to the tail of a list
488  * @param list   List to add pipe to
489  * @param pipe   Pipe to add
490  */
491 static inline void __cvmx_usb_append_pipe(cvmx_usb_pipe_list_t *list, cvmx_usb_pipe_t *pipe)
492 {
493     pipe->next = NULL;
494     pipe->prev = list->tail;
495     if (list->tail)
496         list->tail->next = pipe;
497     else
498         list->head = pipe;
499     list->tail = pipe;
500 }
501
502
503 /**
504  * @INTERNAL
505  * Remove a pipe from a list
506  * @param list   List to remove pipe from
507  * @param pipe   Pipe to remove
508  */
509 static inline void __cvmx_usb_remove_pipe(cvmx_usb_pipe_list_t *list, cvmx_usb_pipe_t *pipe)
510 {
511     if (list->head == pipe)
512     {
513         list->head = pipe->next;
514         pipe->next = NULL;
515         if (list->head)
516             list->head->prev = NULL;
517         else
518             list->tail = NULL;
519     }
520     else if (list->tail == pipe)
521     {
522         list->tail = pipe->prev;
523         list->tail->next = NULL;
524         pipe->prev = NULL;
525     }
526     else
527     {
528         pipe->prev->next = pipe->next;
529         pipe->next->prev = pipe->prev;
530         pipe->prev = NULL;
531         pipe->next = NULL;
532     }
533 }
534
535
536 /**
537  * @INTERNAL
538  * Perfrom USB device mode initialization after a reset completes.
539  * This should be called after USBC0/1_GINTSTS[USBRESET] and
540  * coresponds to section 22.6.1.1, "Initialization on USB Reset",
541  * in the manual.
542  *
543  * @param usb    USB device state populated by
544  *               cvmx_usb_initialize().
545  *
546  * @return CVMX_USB_SUCCESS or a negative error code defined in
547  *         cvmx_usb_status_t.
548  */
549 static cvmx_usb_status_t __cvmx_usb_device_reset_complete(cvmx_usb_internal_state_t *usb)
550 {
551     cvmx_usbcx_ghwcfg3_t usbcx_ghwcfg3;
552     int i;
553
554     CVMX_USB_LOG_CALLED();
555     CVMX_USB_LOG_PARAM("%p", usb);
556
557     /* 1. Set USBC0/1_DOEPCTLn[SNAK] = 1 (for all OUT endpoints, n = 0-4). */
558     for (i=0; i<5; i++)
559     {
560         USB_SET_FIELD32(CVMX_USBCX_DOEPCTLX(i, usb->index),
561                         cvmx_usbcx_doepctlx_t, snak, 1);
562     }
563
564     /* 2. Unmask the following interrupt bits:
565         USBC0/1_DAINTMSK[INEPMSK] = 1 (control 0 IN endpoint)
566         USBC0/1_DAINTMSK[OUTEPMSK] = 1 (control 0 OUT endpoint)
567         USBC0/1_DOEPMSK[SETUPMSK] = 1
568         USBC0/1_DOEPMSK[XFERCOMPLMSK] = 1
569         USBC0/1_DIEPMSK[XFERCOMPLMSK] = 1
570         USBC0/1_DIEPMSK[TIMEOUTMSK] = 1 */
571     USB_SET_FIELD32(CVMX_USBCX_DAINTMSK(usb->index), cvmx_usbcx_daintmsk_t,
572                     inepmsk, 1);
573     USB_SET_FIELD32(CVMX_USBCX_DAINTMSK(usb->index), cvmx_usbcx_daintmsk_t,
574                     outepmsk, 1);
575     USB_SET_FIELD32(CVMX_USBCX_DOEPMSK(usb->index), cvmx_usbcx_doepmsk_t,
576                     setupmsk, 1);
577     USB_SET_FIELD32(CVMX_USBCX_DOEPMSK(usb->index), cvmx_usbcx_doepmsk_t,
578                     xfercomplmsk, 1);
579     USB_SET_FIELD32(CVMX_USBCX_DIEPMSK(usb->index), cvmx_usbcx_diepmsk_t,
580                     xfercomplmsk, 1);
581     USB_SET_FIELD32(CVMX_USBCX_DIEPMSK(usb->index), cvmx_usbcx_diepmsk_t,
582                     timeoutmsk, 1);
583
584     /* 3. To transmit or receive data, the device must initialize more
585         registers as specified in Section 22.6.1.7 */
586     /* Nothing needed */
587
588     /* 4. Set up the data FIFO RAM for each of the FIFOs:
589         Program USBC0/1_GRXFSIZ to be able to receive control OUT data and
590         SETUP data. This must equal at least one maximum packet size of
591         control endpoint 0 + 2 Dwords (for the status of the control OUT
592         data packet) + 10 Dwords (for SETUP packets).
593         Program USBC0/1_GNPTXFSIZ to be able to transmit control IN data. This
594         must equal at least one maximum packet size of control endpoint 0. */
595
596     /* Read the HWCFG3 register so we know how much space is in the FIFO */
597     usbcx_ghwcfg3.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GHWCFG3(usb->index));
598
599     {
600         cvmx_usbcx_gnptxfsiz_t gnptxfsiz;
601         int fifo_space = usbcx_ghwcfg3.s.dfifodepth;
602         int i;
603
604         /* Start at the top of the FIFO and assign space for each periodic
605             fifo */
606         for (i=4;i>0;i--)
607         {
608             cvmx_usbcx_dptxfsizx_t siz;
609             siz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_DPTXFSIZX(i, usb->index));
610             fifo_space -= siz.s.dptxfsize;
611             siz.s.dptxfstaddr = fifo_space;
612             __cvmx_usb_write_csr32(usb, CVMX_USBCX_DPTXFSIZX(i, usb->index), siz.u32);
613         }
614
615         /* Assign half the leftover space to the non periodic tx fifo */
616         gnptxfsiz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GNPTXFSIZ(usb->index));
617         gnptxfsiz.s.nptxfdep = fifo_space / 2;
618         fifo_space -= gnptxfsiz.s.nptxfdep;
619         gnptxfsiz.s.nptxfstaddr = fifo_space;
620         __cvmx_usb_write_csr32(usb, CVMX_USBCX_GNPTXFSIZ(usb->index), gnptxfsiz.u32);
621
622         /* Assign the remain space to the RX fifo */
623         USB_SET_FIELD32(CVMX_USBCX_GRXFSIZ(usb->index), cvmx_usbcx_grxfsiz_t,
624                         rxfdep, fifo_space);
625     }
626
627     /* 5. Program the following fields in the endpoint-specific registers for
628         control OUT endpoint 0 to receive a SETUP packet
629         USBC0/1_DOEPTSIZ0[SUPCNT] = 0x3 (to receive up to three back-to-back
630         SETUP packets)
631         In DMA mode, USBC0/1_DOEPDMA0 register with a memory address to
632         store any SETUP packets received */
633     USB_SET_FIELD32(CVMX_USBCX_DOEPTSIZX(0, usb->index),
634                     cvmx_usbcx_doeptsizx_t, mc, 3);
635     // FIXME
636
637     /* At this point, all initialization required to receive SETUP packets is
638         done. */
639
640     CVMX_USB_RETURN(CVMX_USB_SUCCESS);
641 }
642
643
644 /**
645  * Initialize a USB port for use. This must be called before any
646  * other access to the Octeon USB port is made. The port starts
647  * off in the disabled state.
648  *
649  * @param state  Pointer to an empty cvmx_usb_state_t structure
650  *               that will be populated by the initialize call.
651  *               This structure is then passed to all other USB
652  *               functions.
653  * @param usb_port_number
654  *               Which Octeon USB port to initialize.
655  * @param flags  Flags to control hardware initialization. See
656  *               cvmx_usb_initialize_flags_t for the flag
657  *               definitions. Some flags are mandatory.
658  *
659  * @return CVMX_USB_SUCCESS or a negative error code defined in
660  *         cvmx_usb_status_t.
661  */
662 cvmx_usb_status_t cvmx_usb_initialize(cvmx_usb_state_t *state,
663                                       int usb_port_number,
664                                       cvmx_usb_initialize_flags_t flags)
665 {
666     cvmx_usbnx_clk_ctl_t usbn_clk_ctl;
667     cvmx_usbnx_usbp_ctl_status_t usbn_usbp_ctl_status;
668     cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
669
670     usb->init_flags = flags;
671     CVMX_USB_LOG_CALLED();
672     CVMX_USB_LOG_PARAM("%p", state);
673     CVMX_USB_LOG_PARAM("%d", usb_port_number);
674     CVMX_USB_LOG_PARAM("0x%x", flags);
675
676     /* Make sure that state is large enough to store the internal state */
677     if (sizeof(*state) < sizeof(*usb))
678         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
679     /* At first allow 0-1 for the usb port number */
680     if ((usb_port_number < 0) || (usb_port_number > 1))
681         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
682     /* For all chips except 52XX there is only one port */
683     if (!OCTEON_IS_MODEL(OCTEON_CN52XX) && (usb_port_number > 0))
684         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
685     /* Try to determine clock type automatically */
686     if ((flags & (CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI |
687                   CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND)) == 0)
688     {
689         if (__cvmx_helper_board_usb_get_clock_type() == USB_CLOCK_TYPE_CRYSTAL_12)
690             flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI;  /* Only 12 MHZ crystals are supported */
691         else
692             flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND;
693     }
694
695     if (flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND)
696     {
697         /* Check for auto ref clock frequency */
698         if (!(flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK))
699             switch (__cvmx_helper_board_usb_get_clock_type())
700             {
701                 case USB_CLOCK_TYPE_REF_12:
702                     flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ;
703                     break;
704                 case USB_CLOCK_TYPE_REF_24:
705                     flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ;
706                     break;
707                 case USB_CLOCK_TYPE_REF_48:
708                     flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ;
709                     break;
710                 default:
711                     CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
712                     break;
713             }
714     }
715
716     memset(usb, 0, sizeof(usb));
717     usb->init_flags = flags;
718
719     /* Initialize the USB state structure */
720     {
721         int i;
722         usb->index = usb_port_number;
723
724         /* Initialize the transaction double linked list */
725         usb->free_transaction_head = NULL;
726         usb->free_transaction_tail = NULL;
727         for (i=0; i<MAX_TRANSACTIONS; i++)
728             __cvmx_usb_free_transaction(usb, usb->transaction + i);
729         for (i=0; i<MAX_PIPES; i++)
730             __cvmx_usb_append_pipe(&usb->free_pipes, usb->pipe + i);
731     }
732
733     /* Power On Reset and PHY Initialization */
734
735     /* 1. Wait for DCOK to assert (nothing to do) */
736     /* 2a. Write USBN0/1_CLK_CTL[POR] = 1 and
737         USBN0/1_CLK_CTL[HRST,PRST,HCLK_RST] = 0 */
738     usbn_clk_ctl.u64 = __cvmx_usb_read_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index));
739     usbn_clk_ctl.s.por = 1;
740     usbn_clk_ctl.s.hrst = 0;
741     usbn_clk_ctl.s.prst = 0;
742     usbn_clk_ctl.s.hclk_rst = 0;
743     usbn_clk_ctl.s.enable = 0;
744     /* 2b. Select the USB reference clock/crystal parameters by writing
745         appropriate values to USBN0/1_CLK_CTL[P_C_SEL, P_RTYPE, P_COM_ON] */
746     if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND)
747     {
748         /* The USB port uses 12/24/48MHz 2.5V board clock
749             source at USB_XO. USB_XI should be tied to GND.
750             Most Octeon evaluation boards require this setting */
751         if (OCTEON_IS_MODEL(OCTEON_CN3XXX))
752         {
753             usbn_clk_ctl.cn31xx.p_rclk  = 1; /* From CN31XX,CN30XX manual */
754             usbn_clk_ctl.cn31xx.p_xenbn = 0;
755         }
756         else if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN50XX))
757             usbn_clk_ctl.cn56xx.p_rtype = 2; /* From CN56XX,CN50XX manual */
758         else
759             usbn_clk_ctl.cn52xx.p_rtype = 1; /* From CN52XX manual */
760
761         switch (flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK)
762         {
763             case CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ:
764                 usbn_clk_ctl.s.p_c_sel = 0;
765                 break;
766             case CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ:
767                 usbn_clk_ctl.s.p_c_sel = 1;
768                 break;
769             case CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ:
770                 usbn_clk_ctl.s.p_c_sel = 2;
771                 break;
772         }
773     }
774     else
775     {
776         /* The USB port uses a 12MHz crystal as clock source
777             at USB_XO and USB_XI */
778         if (OCTEON_IS_MODEL(OCTEON_CN3XXX))
779         {
780             usbn_clk_ctl.cn31xx.p_rclk  = 1; /* From CN31XX,CN30XX manual */
781             usbn_clk_ctl.cn31xx.p_xenbn = 1;
782         }
783         else if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN50XX))
784             usbn_clk_ctl.cn56xx.p_rtype = 0; /* From CN56XX,CN50XX manual */
785         else
786             usbn_clk_ctl.cn52xx.p_rtype = 0; /* From CN52XX manual */
787
788         usbn_clk_ctl.s.p_c_sel = 0;
789     }
790     /* 2c. Select the HCLK via writing USBN0/1_CLK_CTL[DIVIDE, DIVIDE2] and
791         setting USBN0/1_CLK_CTL[ENABLE] = 1.  Divide the core clock down such
792         that USB is as close as possible to 125Mhz */
793     {
794         int divisor = (cvmx_sysinfo_get()->cpu_clock_hz+125000000-1)/125000000;
795         if (divisor < 4)  /* Lower than 4 doesn't seem to work properly */
796             divisor = 4;
797         usbn_clk_ctl.s.divide = divisor;
798         usbn_clk_ctl.s.divide2 = 0;
799     }
800     __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
801                            usbn_clk_ctl.u64);
802     /* 2d. Write USBN0/1_CLK_CTL[HCLK_RST] = 1 */
803     usbn_clk_ctl.s.hclk_rst = 1;
804     __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
805                            usbn_clk_ctl.u64);
806     /* 2e.  Wait 64 core-clock cycles for HCLK to stabilize */
807     cvmx_wait(64);
808     /* 3. Program the power-on reset field in the USBN clock-control register:
809         USBN_CLK_CTL[POR] = 0 */
810     usbn_clk_ctl.s.por = 0;
811     __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
812                            usbn_clk_ctl.u64);
813     /* 4. Wait 1 ms for PHY clock to start */
814     cvmx_wait_usec(1000);
815     /* 5. Program the Reset input from automatic test equipment field in the
816         USBP control and status register: USBN_USBP_CTL_STATUS[ATE_RESET] = 1 */
817     usbn_usbp_ctl_status.u64 = __cvmx_usb_read_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index));
818     usbn_usbp_ctl_status.s.ate_reset = 1;
819     __cvmx_usb_write_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index),
820                            usbn_usbp_ctl_status.u64);
821     /* 6. Wait 10 cycles */
822     cvmx_wait(10);
823     /* 7. Clear ATE_RESET field in the USBN clock-control register:
824         USBN_USBP_CTL_STATUS[ATE_RESET] = 0 */
825     usbn_usbp_ctl_status.s.ate_reset = 0;
826     __cvmx_usb_write_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index),
827                            usbn_usbp_ctl_status.u64);
828     /* 8. Program the PHY reset field in the USBN clock-control register:
829         USBN_CLK_CTL[PRST] = 1 */
830     usbn_clk_ctl.s.prst = 1;
831     __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
832                            usbn_clk_ctl.u64);
833     /* 9. Program the USBP control and status register to select host or
834         device mode. USBN_USBP_CTL_STATUS[HST_MODE] = 0 for host, = 1 for
835         device */
836     if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEVICE_MODE)
837     {
838         usbn_usbp_ctl_status.s.hst_mode = 1;
839         usbn_usbp_ctl_status.s.dm_pulld = 0;
840         usbn_usbp_ctl_status.s.dp_pulld = 0;
841     }
842     else
843     {
844         usbn_usbp_ctl_status.s.hst_mode = 0;
845     }
846     __cvmx_usb_write_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index),
847                            usbn_usbp_ctl_status.u64);
848     /* 10. Wait 1 Âµs */
849     cvmx_wait_usec(1);
850     /* 11. Program the hreset_n field in the USBN clock-control register:
851         USBN_CLK_CTL[HRST] = 1 */
852     usbn_clk_ctl.s.hrst = 1;
853     __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
854                            usbn_clk_ctl.u64);
855     /* 12. Proceed to USB core initialization */
856     usbn_clk_ctl.s.enable = 1;
857     __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
858                            usbn_clk_ctl.u64);
859     cvmx_wait_usec(1);
860
861     /* USB Core Initialization */
862
863     /* 1. Read USBC_GHWCFG1, USBC_GHWCFG2, USBC_GHWCFG3, USBC_GHWCFG4 to
864         determine USB core configuration parameters. */
865     /* Nothing needed */
866     /* 2. Program the following fields in the global AHB configuration
867         register (USBC_GAHBCFG)
868         DMA mode, USBC_GAHBCFG[DMAEn]: 1 = DMA mode, 0 = slave mode
869         Burst length, USBC_GAHBCFG[HBSTLEN] = 0
870         Nonperiodic TxFIFO empty level (slave mode only),
871         USBC_GAHBCFG[NPTXFEMPLVL]
872         Periodic TxFIFO empty level (slave mode only),
873         USBC_GAHBCFG[PTXFEMPLVL]
874         Global interrupt mask, USBC_GAHBCFG[GLBLINTRMSK] = 1 */
875     {
876         cvmx_usbcx_gahbcfg_t usbcx_gahbcfg;
877         usbcx_gahbcfg.u32 = 0;
878         usbcx_gahbcfg.s.dmaen = !OCTEON_IS_MODEL(OCTEON_CN31XX);
879         /* If we are using DMA, start off with 8 idle channels. Without
880             DMA we emulate a single channel */
881         if (usbcx_gahbcfg.s.dmaen)
882             usb->idle_hardware_channels = 0xff;
883         else
884             usb->idle_hardware_channels = 0x1;
885         usbcx_gahbcfg.s.hbstlen = 0;
886         usbcx_gahbcfg.s.nptxfemplvl = 1;
887         usbcx_gahbcfg.s.ptxfemplvl = 1;
888         usbcx_gahbcfg.s.glblintrmsk = 1;
889         __cvmx_usb_write_csr32(usb, CVMX_USBCX_GAHBCFG(usb->index),
890                                usbcx_gahbcfg.u32);
891     }
892     /* 3. Program the following fields in USBC_GUSBCFG register.
893         HS/FS timeout calibration, USBC_GUSBCFG[TOUTCAL] = 0
894         ULPI DDR select, USBC_GUSBCFG[DDRSEL] = 0
895         USB turnaround time, USBC_GUSBCFG[USBTRDTIM] = 0x5
896         PHY low-power clock select, USBC_GUSBCFG[PHYLPWRCLKSEL] = 0 */
897     {
898         cvmx_usbcx_gusbcfg_t usbcx_gusbcfg;
899         usbcx_gusbcfg.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GUSBCFG(usb->index));
900         usbcx_gusbcfg.s.toutcal = 0;
901         usbcx_gusbcfg.s.ddrsel = 0;
902         usbcx_gusbcfg.s.usbtrdtim = 0x5;
903         usbcx_gusbcfg.s.phylpwrclksel = 0;
904         __cvmx_usb_write_csr32(usb, CVMX_USBCX_GUSBCFG(usb->index),
905                                usbcx_gusbcfg.u32);
906     }
907     /* 4. The software must unmask the following bits in the USBC_GINTMSK
908         register.
909         OTG interrupt mask, USBC_GINTMSK[OTGINTMSK] = 1
910         Mode mismatch interrupt mask, USBC_GINTMSK[MODEMISMSK] = 1 */
911     {
912         cvmx_usbcx_gintmsk_t usbcx_gintmsk;
913         cvmx_usbcx_hcintmskx_t usbc_hcintmsk;
914         cvmx_usbcx_haintmsk_t usbc_haintmsk;
915         int channel;
916
917         usbcx_gintmsk.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GINTMSK(usb->index));
918         usbcx_gintmsk.s.otgintmsk = 1;
919         usbcx_gintmsk.s.modemismsk = 1;
920         usbcx_gintmsk.s.hchintmsk = 1;
921         usbcx_gintmsk.s.sofmsk = 0;
922         __cvmx_usb_write_csr32(usb, CVMX_USBCX_GINTMSK(usb->index),
923                                usbcx_gintmsk.u32);
924
925         /* Enable the channel halt interrupt */
926         usbc_hcintmsk.u32 = 0;
927         usbc_hcintmsk.s.chhltdmsk = 1;
928         for (channel=0; channel<8; channel++)
929             if (usb->idle_hardware_channels & (1<<channel))
930                 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), usbc_hcintmsk.u32);
931
932         /* Enable the channel interrupt to propagate */
933         usbc_haintmsk.u32 = 0;
934         usbc_haintmsk.s.haintmsk = usb->idle_hardware_channels;
935         __cvmx_usb_write_csr32(usb, CVMX_USBCX_HAINTMSK(usb->index), usbc_haintmsk.u32);
936     }
937
938     if ((usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEVICE_MODE) == 0)
939     {
940         /* Host Port Initialization */
941         if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO))
942             cvmx_dprintf("%s: USB%d is in host mode\n", __FUNCTION__, usb->index);
943
944         /* 1. Program the host-port interrupt-mask field to unmask,
945             USBC_GINTMSK[PRTINT] = 1 */
946         USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), cvmx_usbcx_gintmsk_t,
947                         prtintmsk, 1);
948         USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), cvmx_usbcx_gintmsk_t,
949                         disconnintmsk, 1);
950         /* 2. Program the USBC_HCFG register to select full-speed host or
951             high-speed host. */
952         {
953             cvmx_usbcx_hcfg_t usbcx_hcfg;
954             usbcx_hcfg.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCFG(usb->index));
955             usbcx_hcfg.s.fslssupp = 0;
956             usbcx_hcfg.s.fslspclksel = 0;
957             __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCFG(usb->index), usbcx_hcfg.u32);
958         }
959         /* 3. Program the port power bit to drive VBUS on the USB,
960             USBC_HPRT[PRTPWR] = 1 */
961         USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), cvmx_usbcx_hprt_t, prtpwr, 1);
962
963         /* Steps 4-15 from the manual are done later in the port enable */
964     }
965     else
966     {
967         /* Device Port Initialization */
968         if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO))
969             cvmx_dprintf("%s: USB%d is in device mode\n", __FUNCTION__, usb->index);
970
971         /* 1. Program the following fields in the USBC0/1_DCFG register:
972             Device speed, USBC0/1_DCFG[DEVSPD] = 0 (high speed)
973             Non-zero-length status OUT handshake, USBC0/1_DCFG[NZSTSOUTHSHK]=0
974             Periodic frame interval (if periodic endpoints are supported),
975             USBC0/1_DCFG[PERFRINT] = 1 */
976         USB_SET_FIELD32(CVMX_USBCX_DCFG(usb->index), cvmx_usbcx_dcfg_t,
977                         devspd, 0);
978         USB_SET_FIELD32(CVMX_USBCX_DCFG(usb->index), cvmx_usbcx_dcfg_t,
979                         nzstsouthshk, 0);
980         USB_SET_FIELD32(CVMX_USBCX_DCFG(usb->index), cvmx_usbcx_dcfg_t,
981                         perfrint, 1);
982
983         /* 2. Program the USBC0/1_GINTMSK register to unmask the following
984             interrupts:
985             USB Reset, USBC0/1_GINTMSK[USBRSTMSK] = 1
986             Enumeration done, USBC0/1_GINTMSK[ENUMDONEMSK] = 1
987             SOF, USBC0/1_GINTMSK[SOFMSK] = 1 */
988         USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), cvmx_usbcx_gintmsk_t,
989                         usbrstmsk, 1);
990         USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), cvmx_usbcx_gintmsk_t,
991                         enumdonemsk, 1);
992         USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), cvmx_usbcx_gintmsk_t,
993                         sofmsk, 1);
994
995         /* 3. Wait for the USBC0/1_GINTSTS[USBRESET] interrupt, which
996             indicates a reset has been detected on the USB and lasts for
997             about 10 ms. On receiving this interrupt, the application must
998             perform the steps listed in Section 22.6.1.1, "Initialization on
999             USB Reset". */
1000         /* Handled in cvmx_poll() usbc_gintsts.s.usbrst processing */
1001
1002         /* 4. Wait for the USBC0/1_GINTSTS[ENUMERATIONDONE] interrupt, which
1003             indicates the end of reset on the USB. On receiving this interrupt,
1004             the application must read the USBC0/1_DSTS register to determine
1005             the enumeration speed and perform the steps listed in Section
1006             22.6.1.2, "Initialization on Enumeration Completion". */
1007         /* Handled in cvmx_poll() usbc_gintsts.s.enumdone processing */
1008     }
1009
1010     CVMX_USB_RETURN(CVMX_USB_SUCCESS);
1011 }
1012
1013
1014 /**
1015  * Shutdown a USB port after a call to cvmx_usb_initialize().
1016  * The port should be disabled with all pipes closed when this
1017  * function is called.
1018  *
1019  * @param state  USB device state populated by
1020  *               cvmx_usb_initialize().
1021  *
1022  * @return CVMX_USB_SUCCESS or a negative error code defined in
1023  *         cvmx_usb_status_t.
1024  */
1025 cvmx_usb_status_t cvmx_usb_shutdown(cvmx_usb_state_t *state)
1026 {
1027     cvmx_usbnx_clk_ctl_t usbn_clk_ctl;
1028     cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
1029
1030     CVMX_USB_LOG_CALLED();
1031     CVMX_USB_LOG_PARAM("%p", state);
1032
1033     /* Make sure all pipes are closed */
1034     if (usb->idle_pipes.head ||
1035         usb->active_pipes[CVMX_USB_TRANSFER_ISOCHRONOUS].head ||
1036         usb->active_pipes[CVMX_USB_TRANSFER_INTERRUPT].head ||
1037         usb->active_pipes[CVMX_USB_TRANSFER_CONTROL].head ||
1038         usb->active_pipes[CVMX_USB_TRANSFER_BULK].head)
1039         CVMX_USB_RETURN(CVMX_USB_BUSY);
1040
1041     /* Disable the clocks and put them in power on reset */
1042     usbn_clk_ctl.u64 = __cvmx_usb_read_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index));
1043     usbn_clk_ctl.s.enable = 1;
1044     usbn_clk_ctl.s.por = 1;
1045     usbn_clk_ctl.s.hclk_rst = 1;
1046     usbn_clk_ctl.s.prst = 0;
1047     usbn_clk_ctl.s.hrst = 0;
1048     __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
1049                            usbn_clk_ctl.u64);
1050     CVMX_USB_RETURN(CVMX_USB_SUCCESS);
1051 }
1052
1053
1054 /**
1055  * Enable a USB port. After this call succeeds, the USB port is
1056  * online and servicing requests.
1057  *
1058  * @param state  USB device state populated by
1059  *               cvmx_usb_initialize().
1060  *
1061  * @return CVMX_USB_SUCCESS or a negative error code defined in
1062  *         cvmx_usb_status_t.
1063  */
1064 cvmx_usb_status_t cvmx_usb_enable(cvmx_usb_state_t *state)
1065 {
1066     cvmx_usbcx_ghwcfg3_t usbcx_ghwcfg3;
1067     cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
1068
1069     CVMX_USB_LOG_CALLED();
1070     CVMX_USB_LOG_PARAM("%p", state);
1071     if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEVICE_MODE))
1072         CVMX_USB_RETURN(CVMX_USB_INCORRECT_MODE);
1073
1074     usb->usbcx_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
1075
1076     /* If the port is already enabled the just return. We don't need to do
1077         anything */
1078     if (usb->usbcx_hprt.s.prtena)
1079         CVMX_USB_RETURN(CVMX_USB_SUCCESS);
1080
1081     /* If there is nothing plugged into the port then fail immediately */
1082     if (!usb->usbcx_hprt.s.prtconnsts)
1083     {
1084         if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO))
1085             cvmx_dprintf("%s: USB%d Nothing plugged into the port\n", __FUNCTION__, usb->index);
1086         CVMX_USB_RETURN(CVMX_USB_TIMEOUT);
1087     }
1088
1089     /* Program the port reset bit to start the reset process */
1090     USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), cvmx_usbcx_hprt_t, prtrst, 1);
1091
1092     /* Wait at least 50ms (high speed), or 10ms (full speed) for the reset
1093         process to complete. */
1094     cvmx_wait_usec(50000);
1095
1096     /* Program the port reset bit to 0, USBC_HPRT[PRTRST] = 0 */
1097     USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), cvmx_usbcx_hprt_t, prtrst, 0);
1098
1099     /* Wait for the USBC_HPRT[PRTENA]. */
1100     if (CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_HPRT(usb->index), cvmx_usbcx_hprt_t,
1101                               prtena, ==, 1, 100000))
1102     {
1103         if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO))
1104             cvmx_dprintf("%s: Timeout waiting for the port to finish reset\n",
1105                          __FUNCTION__);
1106         CVMX_USB_RETURN(CVMX_USB_TIMEOUT);
1107     }
1108
1109     /* Read the port speed field to get the enumerated speed, USBC_HPRT[PRTSPD]. */
1110     usb->usbcx_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
1111     if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO))
1112         cvmx_dprintf("%s: USB%d is in %s speed mode\n", __FUNCTION__, usb->index,
1113                      (usb->usbcx_hprt.s.prtspd == CVMX_USB_SPEED_HIGH) ? "high" :
1114                      (usb->usbcx_hprt.s.prtspd == CVMX_USB_SPEED_FULL) ? "full" :
1115                      "low");
1116
1117     usbcx_ghwcfg3.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GHWCFG3(usb->index));
1118
1119     /* 13. Program the USBC_GRXFSIZ register to select the size of the receive
1120         FIFO (25%). */
1121     USB_SET_FIELD32(CVMX_USBCX_GRXFSIZ(usb->index), cvmx_usbcx_grxfsiz_t,
1122                     rxfdep, usbcx_ghwcfg3.s.dfifodepth / 4);
1123     /* 14. Program the USBC_GNPTXFSIZ register to select the size and the
1124         start address of the non- periodic transmit FIFO for nonperiodic
1125         transactions (50%). */
1126     {
1127         cvmx_usbcx_gnptxfsiz_t siz;
1128         siz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GNPTXFSIZ(usb->index));
1129         siz.s.nptxfdep = usbcx_ghwcfg3.s.dfifodepth / 2;
1130         siz.s.nptxfstaddr = usbcx_ghwcfg3.s.dfifodepth / 4;
1131         __cvmx_usb_write_csr32(usb, CVMX_USBCX_GNPTXFSIZ(usb->index), siz.u32);
1132     }
1133     /* 15. Program the USBC_HPTXFSIZ register to select the size and start
1134         address of the periodic transmit FIFO for periodic transactions (25%). */
1135     {
1136         cvmx_usbcx_hptxfsiz_t siz;
1137         siz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPTXFSIZ(usb->index));
1138         siz.s.ptxfsize = usbcx_ghwcfg3.s.dfifodepth / 4;
1139         siz.s.ptxfstaddr = 3 * usbcx_ghwcfg3.s.dfifodepth / 4;
1140         __cvmx_usb_write_csr32(usb, CVMX_USBCX_HPTXFSIZ(usb->index), siz.u32);
1141     }
1142     /* Flush all FIFOs */
1143     USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), cvmx_usbcx_grstctl_t, txfnum, 0x10);
1144     USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), cvmx_usbcx_grstctl_t, txfflsh, 1);
1145     CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), cvmx_usbcx_grstctl_t,
1146                           txfflsh, ==, 0, 100);
1147     USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), cvmx_usbcx_grstctl_t, rxfflsh, 1);
1148     CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), cvmx_usbcx_grstctl_t,
1149                           rxfflsh, ==, 0, 100);
1150
1151     CVMX_USB_RETURN(CVMX_USB_SUCCESS);
1152 }
1153
1154
1155 /**
1156  * Disable a USB port. After this call the USB port will not
1157  * generate data transfers and will not generate events.
1158  * Transactions in process will fail and call their
1159  * associated callbacks.
1160  *
1161  * @param state  USB device state populated by
1162  *               cvmx_usb_initialize().
1163  *
1164  * @return CVMX_USB_SUCCESS or a negative error code defined in
1165  *         cvmx_usb_status_t.
1166  */
1167 cvmx_usb_status_t cvmx_usb_disable(cvmx_usb_state_t *state)
1168 {
1169     cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
1170
1171     CVMX_USB_LOG_CALLED();
1172     CVMX_USB_LOG_PARAM("%p", state);
1173     if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEVICE_MODE))
1174         CVMX_USB_RETURN(CVMX_USB_INCORRECT_MODE);
1175
1176     /* Disable the port */
1177     USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), cvmx_usbcx_hprt_t, prtena, 1);
1178     CVMX_USB_RETURN(CVMX_USB_SUCCESS);
1179 }
1180
1181
1182 /**
1183  * Get the current state of the USB port. Use this call to
1184  * determine if the usb port has anything connected, is enabled,
1185  * or has some sort of error condition. The return value of this
1186  * call has "changed" bits to signal of the value of some fields
1187  * have changed between calls. These "changed" fields are based
1188  * on the last call to cvmx_usb_set_status(). In order to clear
1189  * them, you must update the status through cvmx_usb_set_status().
1190  *
1191  * @param state  USB device state populated by
1192  *               cvmx_usb_initialize().
1193  *
1194  * @return Port status information
1195  */
1196 cvmx_usb_port_status_t cvmx_usb_get_status(cvmx_usb_state_t *state)
1197 {
1198     cvmx_usbcx_hprt_t usbc_hprt;
1199     cvmx_usb_port_status_t result;
1200     cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
1201
1202     memset(&result, 0, sizeof(result));
1203
1204     CVMX_USB_LOG_CALLED();
1205     CVMX_USB_LOG_PARAM("%p", state);
1206
1207     usbc_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
1208     result.port_enabled = usbc_hprt.s.prtena;
1209     result.port_over_current = usbc_hprt.s.prtovrcurract;
1210     result.port_powered = usbc_hprt.s.prtpwr;
1211     result.port_speed = usbc_hprt.s.prtspd;
1212     result.connected = usbc_hprt.s.prtconnsts;
1213     result.connect_change = (result.connected != usb->port_status.connected);
1214
1215     if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CALLS))
1216         cvmx_dprintf("%*s%s: returned port enabled=%d, over_current=%d, powered=%d, speed=%d, connected=%d, connect_change=%d\n",
1217                      2*(--usb->indent), "", __FUNCTION__,
1218                      result.port_enabled,
1219                      result.port_over_current,
1220                      result.port_powered,
1221                      result.port_speed,
1222                      result.connected,
1223                      result.connect_change);
1224     return result;
1225 }
1226
1227
1228 /**
1229  * Set the current state of the USB port. The status is used as
1230  * a reference for the "changed" bits returned by
1231  * cvmx_usb_get_status(). Other than serving as a reference, the
1232  * status passed to this function is not used. No fields can be
1233  * changed through this call.
1234  *
1235  * @param state  USB device state populated by
1236  *               cvmx_usb_initialize().
1237  * @param port_status
1238  *               Port status to set, most like returned by cvmx_usb_get_status()
1239  */
1240 void cvmx_usb_set_status(cvmx_usb_state_t *state, cvmx_usb_port_status_t port_status)
1241 {
1242     cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
1243     CVMX_USB_LOG_CALLED();
1244     CVMX_USB_LOG_PARAM("%p", state);
1245     usb->port_status = port_status;
1246     CVMX_USB_RETURN_NOTHING();
1247 }
1248
1249
1250 /**
1251  * @INTERNAL
1252  * Convert a USB transaction into a handle
1253  *
1254  * @param usb    USB device state populated by
1255  *               cvmx_usb_initialize().
1256  * @param transaction
1257  *               Transaction to get handle for
1258  *
1259  * @return Handle
1260  */
1261 static inline int __cvmx_usb_get_submit_handle(cvmx_usb_internal_state_t *usb,
1262                                         cvmx_usb_transaction_t *transaction)
1263 {
1264     return ((unsigned long)transaction - (unsigned long)usb->transaction) /
1265             sizeof(*transaction);
1266 }
1267
1268
1269 /**
1270  * @INTERNAL
1271  * Convert a USB pipe into a handle
1272  *
1273  * @param usb    USB device state populated by
1274  *               cvmx_usb_initialize().
1275  * @param pipe   Pipe to get handle for
1276  *
1277  * @return Handle
1278  */
1279 static inline int __cvmx_usb_get_pipe_handle(cvmx_usb_internal_state_t *usb,
1280                                         cvmx_usb_pipe_t *pipe)
1281 {
1282     return ((unsigned long)pipe - (unsigned long)usb->pipe) / sizeof(*pipe);
1283 }
1284
1285
1286 /**
1287  * Open a virtual pipe between the host and a USB device. A pipe
1288  * must be opened before data can be transferred between a device
1289  * and Octeon.
1290  *
1291  * @param state      USB device state populated by
1292  *                   cvmx_usb_initialize().
1293  * @param flags      Optional pipe flags defined in
1294  *                   cvmx_usb_pipe_flags_t.
1295  * @param device_addr
1296  *                   USB device address to open the pipe to
1297  *                   (0-127).
1298  * @param endpoint_num
1299  *                   USB endpoint number to open the pipe to
1300  *                   (0-15).
1301  * @param device_speed
1302  *                   The speed of the device the pipe is going
1303  *                   to. This must match the device's speed,
1304  *                   which may be different than the port speed.
1305  * @param max_packet The maximum packet length the device can
1306  *                   transmit/receive (low speed=0-8, full
1307  *                   speed=0-1023, high speed=0-1024). This value
1308  *                   comes from the stadnard endpoint descriptor
1309  *                   field wMaxPacketSize bits <10:0>.
1310  * @param transfer_type
1311  *                   The type of transfer this pipe is for.
1312  * @param transfer_dir
1313  *                   The direction the pipe is in. This is not
1314  *                   used for control pipes.
1315  * @param interval   For ISOCHRONOUS and INTERRUPT transfers,
1316  *                   this is how often the transfer is scheduled
1317  *                   for. All other transfers should specify
1318  *                   zero. The units are in frames (8000/sec at
1319  *                   high speed, 1000/sec for full speed).
1320  * @param multi_count
1321  *                   For high speed devices, this is the maximum
1322  *                   allowed number of packet per microframe.
1323  *                   Specify zero for non high speed devices. This
1324  *                   value comes from the stadnard endpoint descriptor
1325  *                   field wMaxPacketSize bits <12:11>.
1326  * @param hub_device_addr
1327  *                   Hub device address this device is connected
1328  *                   to. Devices connected directly to Octeon
1329  *                   use zero. This is only used when the device
1330  *                   is full/low speed behind a high speed hub.
1331  *                   The address will be of the high speed hub,
1332  *                   not and full speed hubs after it.
1333  * @param hub_port   Which port on the hub the device is
1334  *                   connected. Use zero for devices connected
1335  *                   directly to Octeon. Like hub_device_addr,
1336  *                   this is only used for full/low speed
1337  *                   devices behind a high speed hub.
1338  *
1339  * @return A non negative value is a pipe handle. Negative
1340  *         values are failure codes from cvmx_usb_status_t.
1341  */
1342 int cvmx_usb_open_pipe(cvmx_usb_state_t *state, cvmx_usb_pipe_flags_t flags,
1343                        int device_addr, int endpoint_num,
1344                        cvmx_usb_speed_t device_speed, int max_packet,
1345                        cvmx_usb_transfer_t transfer_type,
1346                        cvmx_usb_direction_t transfer_dir, int interval,
1347                        int multi_count, int hub_device_addr, int hub_port)
1348 {
1349     cvmx_usb_pipe_t *pipe;
1350     cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
1351
1352     CVMX_USB_LOG_CALLED();
1353     CVMX_USB_LOG_PARAM("%p", state);
1354     CVMX_USB_LOG_PARAM("0x%x", flags);
1355     CVMX_USB_LOG_PARAM("%d", device_addr);
1356     CVMX_USB_LOG_PARAM("%d", endpoint_num);
1357     CVMX_USB_LOG_PARAM("%d", device_speed);
1358     CVMX_USB_LOG_PARAM("%d", max_packet);
1359     CVMX_USB_LOG_PARAM("%d", transfer_type);
1360     CVMX_USB_LOG_PARAM("%d", transfer_dir);
1361     CVMX_USB_LOG_PARAM("%d", interval);
1362     CVMX_USB_LOG_PARAM("%d", multi_count);
1363     CVMX_USB_LOG_PARAM("%d", hub_device_addr);
1364     CVMX_USB_LOG_PARAM("%d", hub_port);
1365
1366     if (cvmx_unlikely((device_addr < 0) || (device_addr > MAX_USB_ADDRESS)))
1367         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
1368     if (cvmx_unlikely((endpoint_num < 0) || (endpoint_num > MAX_USB_ENDPOINT)))
1369         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
1370     if (cvmx_unlikely(device_speed > CVMX_USB_SPEED_LOW))
1371         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
1372     if (cvmx_unlikely((max_packet <= 0) || (max_packet > 1024)))
1373         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
1374     if (cvmx_unlikely(transfer_type > CVMX_USB_TRANSFER_INTERRUPT))
1375         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
1376     if (cvmx_unlikely((transfer_dir != CVMX_USB_DIRECTION_OUT) &&
1377         (transfer_dir != CVMX_USB_DIRECTION_IN)))
1378         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
1379     if (cvmx_unlikely(interval < 0))
1380         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
1381     if (cvmx_unlikely((transfer_type == CVMX_USB_TRANSFER_CONTROL) && interval))
1382         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
1383     if (cvmx_unlikely(multi_count < 0))
1384         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
1385     if (cvmx_unlikely((device_speed != CVMX_USB_SPEED_HIGH) &&
1386         (multi_count != 0)))
1387         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
1388     if (cvmx_unlikely((hub_device_addr < 0) || (hub_device_addr > MAX_USB_ADDRESS)))
1389         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
1390     if (cvmx_unlikely((hub_port < 0) || (hub_port > MAX_USB_HUB_PORT)))
1391         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
1392     if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEVICE_MODE))
1393         CVMX_USB_RETURN(CVMX_USB_INCORRECT_MODE);
1394
1395     /* Find a free pipe */
1396     pipe = usb->free_pipes.head;
1397     if (!pipe)
1398         CVMX_USB_RETURN(CVMX_USB_NO_MEMORY);
1399     __cvmx_usb_remove_pipe(&usb->free_pipes, pipe);
1400     pipe->flags = flags | __CVMX_USB_PIPE_FLAGS_OPEN;
1401     if ((device_speed == CVMX_USB_SPEED_HIGH) &&
1402         (transfer_dir == CVMX_USB_DIRECTION_OUT) &&
1403         (transfer_type == CVMX_USB_TRANSFER_BULK))
1404         pipe->flags |= __CVMX_USB_PIPE_FLAGS_NEED_PING;
1405     pipe->device_addr = device_addr;
1406     pipe->endpoint_num = endpoint_num;
1407     pipe->device_speed = device_speed;
1408     pipe->max_packet = max_packet;
1409     pipe->transfer_type = transfer_type;
1410     pipe->transfer_dir = transfer_dir;
1411     /* All pipes use interval to rate limit NAK processing. Force an interval
1412         if one wasn't supplied */
1413     if (!interval)
1414         interval = 1;
1415     if (device_speed == CVMX_USB_SPEED_HIGH)
1416         pipe->interval = (uint64_t)interval * cvmx_sysinfo_get()->cpu_clock_hz / 8000;
1417     else
1418         pipe->interval = (uint64_t)interval * cvmx_sysinfo_get()->cpu_clock_hz / 1000;
1419     pipe->multi_count = multi_count;
1420     pipe->hub_device_addr = hub_device_addr;
1421     pipe->hub_port = hub_port;
1422     pipe->pid_toggle = 0;
1423     pipe->next_tx_cycle = cvmx_read64_uint64(CVMX_IPD_CLK_COUNT) + pipe->interval;
1424     pipe->split_sc_frame = -1;
1425     __cvmx_usb_append_pipe(&usb->idle_pipes, pipe);
1426
1427     /* We don't need to tell the hardware about this pipe yet since
1428         it doesn't have any submitted requests */
1429
1430     CVMX_USB_RETURN(__cvmx_usb_get_pipe_handle(usb, pipe));
1431 }
1432
1433
1434 /**
1435  * @INTERNAL
1436  * Perform channel specific setup for Control transactions. All
1437  * the generic stuff will already have been done in
1438  * __cvmx_usb_start_channel()
1439  *
1440  * @param usb     USB device state populated by
1441  *                cvmx_usb_initialize().
1442  * @param channel Channel to setup
1443  * @param pipe    Pipe for control transaction
1444  */
1445 static void __cvmx_usb_start_channel_control(cvmx_usb_internal_state_t *usb,
1446                                              int channel,
1447                                              cvmx_usb_pipe_t *pipe)
1448 {
1449     cvmx_usb_transaction_t *transaction = pipe->head;
1450     cvmx_usb_control_header_t *header = cvmx_phys_to_ptr(transaction->control_header);
1451     int bytes_to_transfer = transaction->buffer_length - transaction->actual_bytes;
1452     cvmx_usbcx_hctsizx_t usbc_hctsiz;
1453
1454     CVMX_USB_LOG_CALLED();
1455     CVMX_USB_LOG_PARAM("%p", usb);
1456     CVMX_USB_LOG_PARAM("%d", channel);
1457     CVMX_USB_LOG_PARAM("%p", pipe);
1458
1459     usbc_hctsiz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index));
1460
1461     switch (transaction->stage)
1462     {
1463         case CVMX_USB_STAGE_NON_CONTROL:
1464         case CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE:
1465             cvmx_dprintf("%s: ERROR - Non control stage\n", __FUNCTION__);
1466             break;
1467         case CVMX_USB_STAGE_SETUP:
1468             usbc_hctsiz.s.pid = 3; /* Setup */
1469             usbc_hctsiz.s.xfersize = sizeof(*header);
1470             /* All Control operations start with a setup going OUT */
1471             USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), cvmx_usbcx_hccharx_t, epdir, CVMX_USB_DIRECTION_OUT);
1472             /* Setup send the control header instead of the buffer data. The
1473                 buffer data will be used in the next stage */
1474             __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8, transaction->control_header);
1475             break;
1476         case CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE:
1477             usbc_hctsiz.s.pid = 3; /* Setup */
1478             usbc_hctsiz.s.xfersize = 0;
1479             /* All Control operations start with a setup going OUT */
1480             USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), cvmx_usbcx_hccharx_t, epdir, CVMX_USB_DIRECTION_OUT);
1481             USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index), cvmx_usbcx_hcspltx_t, compsplt, 1);
1482             break;
1483         case CVMX_USB_STAGE_DATA:
1484             usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
1485             if (__cvmx_usb_pipe_needs_split(usb, pipe))
1486             {
1487                 usbc_hctsiz.s.xfersize = (header->s.request_type & 0x80) ? 0 : bytes_to_transfer;
1488                 if (usbc_hctsiz.s.xfersize > pipe->max_packet)
1489                     usbc_hctsiz.s.xfersize = pipe->max_packet;
1490             }
1491             else
1492                 usbc_hctsiz.s.xfersize = bytes_to_transfer;
1493             USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
1494                             cvmx_usbcx_hccharx_t, epdir,
1495                             ((header->s.request_type & 0x80) ?
1496                              CVMX_USB_DIRECTION_IN :
1497                              CVMX_USB_DIRECTION_OUT));
1498             break;
1499         case CVMX_USB_STAGE_DATA_SPLIT_COMPLETE:
1500             usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
1501             usbc_hctsiz.s.xfersize = (header->s.request_type & 0x80) ? bytes_to_transfer : 0;
1502             USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
1503                             cvmx_usbcx_hccharx_t, epdir,
1504                             ((header->s.request_type & 0x80) ?
1505                              CVMX_USB_DIRECTION_IN :
1506                              CVMX_USB_DIRECTION_OUT));
1507             USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index), cvmx_usbcx_hcspltx_t, compsplt, 1);
1508             break;
1509         case CVMX_USB_STAGE_STATUS:
1510             usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
1511             usbc_hctsiz.s.xfersize = 0;
1512             USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), cvmx_usbcx_hccharx_t, epdir,
1513                             ((header->s.request_type & 0x80) ?
1514                              CVMX_USB_DIRECTION_OUT :
1515                              CVMX_USB_DIRECTION_IN));
1516             break;
1517         case CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE:
1518             usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
1519             usbc_hctsiz.s.xfersize = 0;
1520             USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), cvmx_usbcx_hccharx_t, epdir,
1521                             ((header->s.request_type & 0x80) ?
1522                              CVMX_USB_DIRECTION_OUT :
1523                              CVMX_USB_DIRECTION_IN));
1524             USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index), cvmx_usbcx_hcspltx_t, compsplt, 1);
1525             break;
1526     }
1527
1528     /* Set the number of packets needed for this transfer */
1529     usbc_hctsiz.s.pktcnt = (usbc_hctsiz.s.xfersize + pipe->max_packet - 1) / pipe->max_packet;
1530     if (!usbc_hctsiz.s.pktcnt)
1531         usbc_hctsiz.s.pktcnt = 1;
1532
1533     __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index), usbc_hctsiz.u32);
1534     CVMX_USB_RETURN_NOTHING();
1535 }
1536
1537
1538 /**
1539  * @INTERNAL
1540  * Start a channel to perform the pipe's head transaction
1541  *
1542  * @param usb     USB device state populated by
1543  *                cvmx_usb_initialize().
1544  * @param channel Channel to setup
1545  * @param pipe    Pipe to start
1546  */
1547 static void __cvmx_usb_start_channel(cvmx_usb_internal_state_t *usb,
1548                                      int channel,
1549                                      cvmx_usb_pipe_t *pipe)
1550 {
1551     cvmx_usb_transaction_t *transaction = pipe->head;
1552     cvmx_usbcx_hfnum_t usbc_hfnum;
1553
1554     CVMX_USB_LOG_CALLED();
1555     CVMX_USB_LOG_PARAM("%p", usb);
1556     CVMX_USB_LOG_PARAM("%d", channel);
1557     CVMX_USB_LOG_PARAM("%p", pipe);
1558
1559     if (cvmx_unlikely((usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_TRANSFERS) ||
1560         (pipe->flags & CVMX_USB_PIPE_FLAGS_DEBUG_TRANSFERS)))
1561         cvmx_dprintf("%s: Channel %d started. Pipe %d transaction %d stage %d\n",
1562                      __FUNCTION__, channel, __cvmx_usb_get_pipe_handle(usb, pipe),
1563                      __cvmx_usb_get_submit_handle(usb, transaction),
1564                      transaction->stage);
1565
1566     /* Make sure all writes to the DMA region get flushed */
1567     CVMX_SYNCW;
1568
1569     /* Read the current frame number for use with split, INTERRUPT,  and ISO
1570         transactions */
1571     usbc_hfnum.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index));
1572
1573     /* Attach the channel to the pipe */
1574     usb->pipe_for_channel[channel] = pipe;
1575     pipe->channel = channel;
1576     pipe->flags |= __CVMX_USB_PIPE_FLAGS_SCHEDULED;
1577
1578     /* Mark this channel as in use */
1579     usb->idle_hardware_channels &= ~(1<<channel);
1580
1581     /* Enable the channel interrupt bits */
1582     {
1583         cvmx_usbcx_hcintx_t usbc_hcint;
1584
1585         /* Clear all channel status bits */
1586         usbc_hcint.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCINTX(channel, usb->index));
1587         __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTX(channel, usb->index), usbc_hcint.u32);
1588     }
1589
1590     /* Setup the locations the DMA engines use  */
1591     {
1592         uint64_t dma_address = transaction->buffer + transaction->actual_bytes;
1593         if (transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS)
1594             dma_address = transaction->buffer + transaction->iso_packets[0].offset + transaction->actual_bytes;
1595         __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8, dma_address);
1596         __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_INB_CHN0(usb->index) + channel*8, dma_address);
1597     }
1598
1599     /* Setup both the size of the transfer and the SPLIT characteristics */
1600     {
1601         cvmx_usbcx_hcspltx_t usbc_hcsplt = {.u32 = 0};
1602         cvmx_usbcx_hctsizx_t usbc_hctsiz = {.u32 = 0};
1603         int bytes_to_transfer = transaction->buffer_length - transaction->actual_bytes;
1604
1605         /* ISOCHRONOUS transactions store each individual transfer size in the
1606             packet structure, not the global buffer_length */
1607         if (transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS)
1608             bytes_to_transfer = transaction->iso_packets[0].length - transaction->actual_bytes;
1609
1610         /* We need to do split transactions when we are talking to non high
1611             speed devices that are behind a high speed hub */
1612         if (__cvmx_usb_pipe_needs_split(usb, pipe))
1613         {
1614             /* On the start split phase (stage is even) record the frame number we
1615                 will need to send the split complete. We only store the lower two bits
1616                 since the time ahead can only be two frames */
1617             if ((transaction->stage&1) == 0)
1618             {
1619                 if (transaction->type == CVMX_USB_TRANSFER_BULK)
1620                     pipe->split_sc_frame = (usbc_hfnum.s.frnum + 1) & 0x7f;
1621                 else
1622                     pipe->split_sc_frame = (usbc_hfnum.s.frnum + 2) & 0x7f;
1623             }
1624             else
1625                 pipe->split_sc_frame = -1;
1626
1627             usbc_hcsplt.s.spltena = 1;
1628             usbc_hcsplt.s.hubaddr = pipe->hub_device_addr;
1629             usbc_hcsplt.s.prtaddr = pipe->hub_port;
1630             usbc_hcsplt.s.compsplt = (transaction->stage == CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE);
1631
1632             /* SPLIT transactions can only ever transmit one data packet so
1633                 limit the transfer size to the max packet size */
1634             if (bytes_to_transfer > pipe->max_packet)
1635                 bytes_to_transfer = pipe->max_packet;
1636
1637             /* ISOCHRONOUS OUT splits are unique in that they limit
1638                 data transfers to 188 byte chunks representing the
1639                 begin/middle/end of the data or all */
1640             if (!usbc_hcsplt.s.compsplt &&
1641                 (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) &&
1642                 (pipe->transfer_type == CVMX_USB_TRANSFER_ISOCHRONOUS))
1643             {
1644                 /* See if we've started this tranfer and sent data */
1645                 if (transaction->actual_bytes == 0)
1646                 {
1647                     /* Nothing sent yet, this is either a begin or the
1648                         entire payload */
1649                     if (bytes_to_transfer <= 188)
1650                         usbc_hcsplt.s.xactpos = 3; /* Entire payload in one go */
1651                     else
1652                         usbc_hcsplt.s.xactpos = 2; /* First part of payload */
1653                 }
1654                 else
1655                 {
1656                     /* Continuing the previous data, we must either be
1657                         in the middle or at the end */
1658                     if (bytes_to_transfer <= 188)
1659                         usbc_hcsplt.s.xactpos = 1; /* End of payload */
1660                     else
1661                         usbc_hcsplt.s.xactpos = 0; /* Middle of payload */
1662                 }
1663                 /* Again, the transfer size is limited to 188 bytes */
1664                 if (bytes_to_transfer > 188)
1665                     bytes_to_transfer = 188;
1666             }
1667         }
1668
1669         usbc_hctsiz.s.xfersize = bytes_to_transfer;
1670         usbc_hctsiz.s.pktcnt = (bytes_to_transfer + pipe->max_packet - 1) / pipe->max_packet;
1671         if (!usbc_hctsiz.s.pktcnt)
1672             usbc_hctsiz.s.pktcnt = 1;
1673
1674         /* Update the DATA0/DATA1 toggle */
1675         usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
1676         /* High speed pipes may need a hardware ping before they start */
1677         if (pipe->flags & __CVMX_USB_PIPE_FLAGS_NEED_PING)
1678             usbc_hctsiz.s.dopng = 1;
1679
1680         __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCSPLTX(channel, usb->index), usbc_hcsplt.u32);
1681         __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index), usbc_hctsiz.u32);
1682     }
1683
1684     /* Setup the Host Channel Characteristics Register */
1685     {
1686         cvmx_usbcx_hccharx_t usbc_hcchar = {.u32 = 0};
1687
1688         /* Make all transfers start on the next frame and not this one. This
1689             way the time we spend processing doesn't affect USB timing */
1690         usbc_hcchar.s.oddfrm = !(usbc_hfnum.s.frnum&1);
1691
1692         /* Set the number of back to back packets allowed by this endpoint.
1693             Split transactions interpret "ec" as the number of immediate
1694             retries of failure. These retries happen too quickly, so we
1695             disable these entirely for splits */
1696         if (__cvmx_usb_pipe_needs_split(usb, pipe))
1697             usbc_hcchar.s.ec = 1;
1698         else if (pipe->multi_count < 1)
1699             usbc_hcchar.s.ec = 1;
1700         else if (pipe->multi_count > 3)
1701             usbc_hcchar.s.ec = 3;
1702         else
1703             usbc_hcchar.s.ec = pipe->multi_count;
1704
1705         /* Set the rest of the endpoint specific settings */
1706         usbc_hcchar.s.devaddr = pipe->device_addr;
1707         usbc_hcchar.s.eptype = transaction->type;
1708         usbc_hcchar.s.lspddev = (pipe->device_speed == CVMX_USB_SPEED_LOW);
1709         usbc_hcchar.s.epdir = pipe->transfer_dir;
1710         usbc_hcchar.s.epnum = pipe->endpoint_num;
1711         usbc_hcchar.s.mps = pipe->max_packet;
1712         __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index), usbc_hcchar.u32);
1713     }
1714
1715     /* Do transaction type specific fixups as needed */
1716     switch (transaction->type)
1717     {
1718         case CVMX_USB_TRANSFER_CONTROL:
1719             __cvmx_usb_start_channel_control(usb, channel, pipe);
1720             break;
1721         case CVMX_USB_TRANSFER_BULK:
1722         case CVMX_USB_TRANSFER_INTERRUPT:
1723             break;
1724         case CVMX_USB_TRANSFER_ISOCHRONOUS:
1725             if (!__cvmx_usb_pipe_needs_split(usb, pipe))
1726             {
1727                 /* ISO transactions require differnet PIDs depending on direction
1728                     and how many packets are needed */
1729                 if (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT)
1730                 {
1731                     if (pipe->multi_count < 2) /* Need DATA0 */
1732                         USB_SET_FIELD32(CVMX_USBCX_HCTSIZX(channel, usb->index), cvmx_usbcx_hctsizx_t, pid, 0);
1733                     else /* Need MDATA */
1734                         USB_SET_FIELD32(CVMX_USBCX_HCTSIZX(channel, usb->index), cvmx_usbcx_hctsizx_t, pid, 3);
1735                 }
1736             }
1737             break;
1738     }
1739     {
1740         cvmx_usbcx_hctsizx_t usbc_hctsiz = {.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index))};
1741         transaction->xfersize = usbc_hctsiz.s.xfersize;
1742         transaction->pktcnt = usbc_hctsiz.s.pktcnt;
1743     }
1744     USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), cvmx_usbcx_hccharx_t, chena, 1);
1745     CVMX_USB_RETURN_NOTHING();
1746 }
1747
1748
1749 /**
1750  * @INTERNAL
1751  * Find a pipe that is ready to be scheduled to hardware.
1752  *
1753  * @param list       Pipe list to search
1754  * @param usbc_hfnum Current USB frame number
1755  * @param current_cycle
1756  *                   Cycle counter to use as a time reference.
1757  *
1758  * @return Pipe or NULL if none are ready
1759  */
1760 static cvmx_usb_pipe_t *__cvmx_usb_find_ready_pipe(cvmx_usb_pipe_list_t *list, cvmx_usbcx_hfnum_t usbc_hfnum, uint64_t current_cycle)
1761 {
1762     cvmx_usb_pipe_t *pipe = list->head;
1763     while (pipe)
1764     {
1765         if (!(pipe->flags & __CVMX_USB_PIPE_FLAGS_SCHEDULED) && pipe->head &&
1766             (pipe->next_tx_cycle <= current_cycle) &&
1767             ((pipe->split_sc_frame == -1) || ((((int)usbc_hfnum.s.frnum - (int)pipe->split_sc_frame) & 0x7f) < 0x40)))
1768         {
1769             CVMX_PREFETCH(pipe, 128);
1770             CVMX_PREFETCH(pipe->head, 0);
1771             return pipe;
1772         }
1773         pipe = pipe->next;
1774     }
1775     return NULL;
1776 }
1777
1778
1779 /**
1780  * @INTERNAL
1781  * Called whenever a pipe might need to be scheduled to the
1782  * hardware.
1783  *
1784  * @param usb    USB device state populated by
1785  *               cvmx_usb_initialize().
1786  * @param is_sof True if this schedule was called on a SOF interrupt.
1787  */
1788 static void __cvmx_usb_schedule(cvmx_usb_internal_state_t *usb, int is_sof)
1789 {
1790     int channel;
1791     cvmx_usb_pipe_t *pipe;
1792     cvmx_usbcx_hfnum_t usbc_hfnum;
1793     uint64_t current_cycle = cvmx_read64_uint64(CVMX_IPD_CLK_COUNT);
1794
1795     CVMX_USB_LOG_CALLED();
1796     CVMX_USB_LOG_PARAM("%p", usb);
1797
1798     usbc_hfnum.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index));
1799
1800     while (usb->idle_hardware_channels)
1801     {
1802         /* Find an idle channel */
1803         CVMX_CLZ(channel, usb->idle_hardware_channels);
1804         channel = 31 - channel;
1805         if (cvmx_unlikely(channel > 7))
1806         {
1807             if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO))
1808                 cvmx_dprintf("%s: Idle hardware channels has a channel higher than 7. This is wrong\n", __FUNCTION__);
1809             break;
1810         }
1811
1812         /* Find a pipe needing service */
1813         pipe = NULL;
1814         if (is_sof)
1815         {
1816             /* Only process periodic pipes on SOF interrupts. This way we are
1817                 sure that the periodic data is sent in the beginning of the
1818                 frame */
1819             pipe = __cvmx_usb_find_ready_pipe(usb->active_pipes + CVMX_USB_TRANSFER_ISOCHRONOUS, usbc_hfnum, current_cycle);
1820             if (cvmx_likely(!pipe))
1821                 pipe = __cvmx_usb_find_ready_pipe(usb->active_pipes + CVMX_USB_TRANSFER_INTERRUPT, usbc_hfnum, current_cycle);
1822         }
1823         if (cvmx_likely(!pipe))
1824         {
1825             pipe = __cvmx_usb_find_ready_pipe(usb->active_pipes + CVMX_USB_TRANSFER_CONTROL, usbc_hfnum, current_cycle);
1826             if (cvmx_likely(!pipe))
1827                 pipe = __cvmx_usb_find_ready_pipe(usb->active_pipes + CVMX_USB_TRANSFER_BULK, usbc_hfnum, current_cycle);
1828         }
1829         if (!pipe)
1830             break;
1831
1832         CVMX_USB_LOG_PARAM("%d", channel);
1833         CVMX_USB_LOG_PARAM("%p", pipe);
1834
1835         if (cvmx_unlikely((usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_TRANSFERS) ||
1836             (pipe->flags & CVMX_USB_PIPE_FLAGS_DEBUG_TRANSFERS)))
1837         {
1838             cvmx_usb_transaction_t *transaction = pipe->head;
1839             const cvmx_usb_control_header_t *header = (transaction->control_header) ? cvmx_phys_to_ptr(transaction->control_header) : NULL;
1840             const char *dir = (pipe->transfer_dir == CVMX_USB_DIRECTION_IN) ? "IN" : "OUT";
1841             const char *type;
1842             switch (pipe->transfer_type)
1843             {
1844                 case CVMX_USB_TRANSFER_CONTROL:
1845                     type = "SETUP";
1846                     dir = (header->s.request_type & 0x80) ? "IN" : "OUT";
1847                     break;
1848                 case CVMX_USB_TRANSFER_ISOCHRONOUS:
1849                     type = "ISOCHRONOUS";
1850                     break;
1851                 case CVMX_USB_TRANSFER_BULK:
1852                     type = "BULK";
1853                     break;
1854                 default: /* CVMX_USB_TRANSFER_INTERRUPT */
1855                     type = "INTERRUPT";
1856                     break;
1857             }
1858             cvmx_dprintf("%s: Starting pipe %d, transaction %d on channel %d. %s %s len=%d header=0x%llx\n",
1859                          __FUNCTION__, __cvmx_usb_get_pipe_handle(usb, pipe),
1860                          __cvmx_usb_get_submit_handle(usb, transaction),
1861                          channel, type, dir,
1862                          transaction->buffer_length,
1863                          (header) ? (unsigned long long)header->u64 : 0ull);
1864         }
1865         __cvmx_usb_start_channel(usb, channel, pipe);
1866     }
1867     CVMX_USB_RETURN_NOTHING();
1868 }
1869
1870
1871 /**
1872  * @INTERNAL
1873  * Call a user's callback for a specific reason.
1874  *
1875  * @param usb    USB device state populated by
1876  *               cvmx_usb_initialize().
1877  * @param pipe   Pipe the callback is for or NULL
1878  * @param transaction
1879  *               Transaction the callback is for or NULL
1880  * @param reason Reason this callback is being called
1881  * @param complete_code
1882  *               Completion code for the transaction, if any
1883  */
1884 static void __cvmx_usb_perform_callback(cvmx_usb_internal_state_t *usb,
1885                                         cvmx_usb_pipe_t *pipe,
1886                                         cvmx_usb_transaction_t *transaction,
1887                                         cvmx_usb_callback_t reason,
1888                                         cvmx_usb_complete_t complete_code)
1889 {
1890     cvmx_usb_callback_func_t callback = usb->callback[reason];
1891     void *user_data = usb->callback_data[reason];
1892     int submit_handle = -1;
1893     int pipe_handle = -1;
1894     int bytes_transferred = 0;
1895
1896     if (pipe)
1897         pipe_handle = __cvmx_usb_get_pipe_handle(usb, pipe);
1898
1899     if (transaction)
1900     {
1901         submit_handle = __cvmx_usb_get_submit_handle(usb, transaction);
1902         bytes_transferred = transaction->actual_bytes;
1903         /* Transactions are allowed to override the default callback */
1904         if ((reason == CVMX_USB_CALLBACK_TRANSFER_COMPLETE) && transaction->callback)
1905         {
1906             callback = transaction->callback;
1907             user_data = transaction->callback_data;
1908         }
1909     }
1910
1911     if (!callback)
1912         return;
1913
1914     if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CALLBACKS))
1915         cvmx_dprintf("%*s%s: calling callback %p(usb=%p, complete_code=%s, "
1916                      "pipe_handle=%d, submit_handle=%d, bytes_transferred=%d, user_data=%p);\n",
1917                      2*usb->indent, "", __FUNCTION__, callback, usb,
1918                      __cvmx_usb_complete_to_string(complete_code),
1919                      pipe_handle, submit_handle, bytes_transferred, user_data);
1920
1921     callback((cvmx_usb_state_t *)usb, reason, complete_code, pipe_handle, submit_handle,
1922              bytes_transferred, user_data);
1923
1924     if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CALLBACKS))
1925         cvmx_dprintf("%*s%s: callback %p complete\n", 2*usb->indent, "",
1926                       __FUNCTION__, callback);
1927 }
1928
1929
1930 /**
1931  * @INTERNAL
1932  * Signal the completion of a transaction and free it. The
1933  * transaction will be removed from the pipe transaction list.
1934  *
1935  * @param usb    USB device state populated by
1936  *               cvmx_usb_initialize().
1937  * @param pipe   Pipe the transaction is on
1938  * @param transaction
1939  *               Transaction that completed
1940  * @param complete_code
1941  *               Completion code
1942  */
1943 static void __cvmx_usb_perform_complete(cvmx_usb_internal_state_t * usb,
1944                                         cvmx_usb_pipe_t *pipe,
1945                                         cvmx_usb_transaction_t *transaction,
1946                                         cvmx_usb_complete_t complete_code)
1947 {
1948     CVMX_USB_LOG_CALLED();
1949     CVMX_USB_LOG_PARAM("%p", usb);
1950     CVMX_USB_LOG_PARAM("%p", pipe);
1951     CVMX_USB_LOG_PARAM("%p", transaction);
1952     CVMX_USB_LOG_PARAM("%d", complete_code);
1953
1954     /* Isochronous transactions need extra processing as they might not be done
1955         after a single data transfer */
1956     if (cvmx_unlikely(transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS))
1957     {
1958         /* Update the number of bytes transfered in this ISO packet */
1959         transaction->iso_packets[0].length = transaction->actual_bytes;
1960         transaction->iso_packets[0].status = complete_code;
1961
1962         /* If there are more ISOs pending and we suceeded, schedule the next
1963             one */
1964         if ((transaction->iso_number_packets > 1) && (complete_code == CVMX_USB_COMPLETE_SUCCESS))
1965         {
1966             transaction->actual_bytes = 0;      /* No bytes transfered for this packet as of yet */
1967             transaction->iso_number_packets--;  /* One less ISO waiting to transfer */
1968             transaction->iso_packets++;         /* Increment to the next location in our packet array */
1969             transaction->stage = CVMX_USB_STAGE_NON_CONTROL;
1970             goto done;
1971         }
1972     }
1973
1974     /* Remove the transaction from the pipe list */
1975     if (transaction->next)
1976         transaction->next->prev = transaction->prev;
1977     else
1978         pipe->tail = transaction->prev;
1979     if (transaction->prev)
1980         transaction->prev->next = transaction->next;
1981     else
1982         pipe->head = transaction->next;
1983     if (!pipe->head)
1984     {
1985         __cvmx_usb_remove_pipe(usb->active_pipes + pipe->transfer_type, pipe);
1986         __cvmx_usb_append_pipe(&usb->idle_pipes, pipe);
1987
1988     }
1989     __cvmx_usb_perform_callback(usb, pipe, transaction,
1990                                 CVMX_USB_CALLBACK_TRANSFER_COMPLETE,
1991                                 complete_code);
1992     __cvmx_usb_free_transaction(usb, transaction);
1993     /* Disable SOF interrupts if we don't have any pending transactions */
1994     usb->active_transactions--;
1995     if (usb->active_transactions == 0)
1996         USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), cvmx_usbcx_gintmsk_t, sofmsk, 0);
1997 done:
1998     CVMX_USB_RETURN_NOTHING();
1999 }
2000
2001
2002 /**
2003  * @INTERNAL
2004  * Submit a usb transaction to a pipe. Called for all types
2005  * of transactions.
2006  *
2007  * @param usb
2008  * @param pipe_handle
2009  *                  Which pipe to submit to. Will be validated in this function.
2010  * @param type      Transaction type
2011  * @param flags     Flags for the transaction
2012  * @param buffer    User buffer for the transaction
2013  * @param buffer_length
2014  *                  User buffer's length in bytes
2015  * @param control_header
2016  *                  For control transactions, the 8 byte standard header
2017  * @param iso_start_frame
2018  *                  For ISO transactiosn, the start frame
2019  * @param iso_number_packets
2020  *                  For ISO, the number of packet in the transaction.
2021  * @param iso_packets
2022  *                  A description of each ISO packet
2023  * @param callback  User callback to call when the transaction completes
2024  * @param user_data User's data for the callback
2025  *
2026  * @return Submit handle or negative on failure. Matches the result
2027  *         in the external API.
2028  */
2029 static int __cvmx_usb_submit_transaction(cvmx_usb_internal_state_t *usb,
2030                                          int pipe_handle,
2031                                          cvmx_usb_transfer_t type,
2032                                          int flags,
2033                                          uint64_t buffer,
2034                                          int buffer_length,
2035                                          uint64_t control_header,
2036                                          int iso_start_frame,
2037                                          int iso_number_packets,
2038                                          cvmx_usb_iso_packet_t *iso_packets,
2039                                          cvmx_usb_callback_func_t callback,
2040                                          void *user_data)
2041 {
2042     int submit_handle;
2043     cvmx_usb_transaction_t *transaction;
2044     cvmx_usb_pipe_t *pipe = usb->pipe + pipe_handle;
2045
2046     CVMX_USB_LOG_CALLED();
2047     if (cvmx_unlikely((pipe_handle < 0) || (pipe_handle >= MAX_PIPES)))
2048         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2049     /* Fail if the pipe isn't open */
2050     if (cvmx_unlikely((pipe->flags & __CVMX_USB_PIPE_FLAGS_OPEN) == 0))
2051         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2052     if (cvmx_unlikely(pipe->transfer_type != type))
2053         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2054
2055     transaction = __cvmx_usb_alloc_transaction(usb);
2056     if (cvmx_unlikely(!transaction))
2057         CVMX_USB_RETURN(CVMX_USB_NO_MEMORY);
2058
2059     /* Enable SOF interrupts now that we have pending transactions */
2060     if (usb->active_transactions == 0)
2061         USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), cvmx_usbcx_gintmsk_t, sofmsk, 1);
2062     usb->active_transactions++;
2063
2064     transaction->type = type;
2065     transaction->flags |= flags;
2066     transaction->buffer = buffer;
2067     transaction->buffer_length = buffer_length;
2068     transaction->control_header = control_header;
2069     transaction->iso_start_frame = iso_start_frame; // FIXME: This is not used, implement it
2070     transaction->iso_number_packets = iso_number_packets;
2071     transaction->iso_packets = iso_packets;
2072     transaction->callback = callback;
2073     transaction->callback_data = user_data;
2074     if (transaction->type == CVMX_USB_TRANSFER_CONTROL)
2075         transaction->stage = CVMX_USB_STAGE_SETUP;
2076     else
2077         transaction->stage = CVMX_USB_STAGE_NON_CONTROL;
2078
2079     transaction->next = NULL;
2080     if (pipe->tail)
2081     {
2082         transaction->prev = pipe->tail;
2083         transaction->prev->next = transaction;
2084     }
2085     else
2086     {
2087         transaction->prev = NULL;
2088         pipe->head = transaction;
2089         __cvmx_usb_remove_pipe(&usb->idle_pipes, pipe);
2090         __cvmx_usb_append_pipe(usb->active_pipes + pipe->transfer_type, pipe);
2091     }
2092     pipe->tail = transaction;
2093
2094     submit_handle = __cvmx_usb_get_submit_handle(usb, transaction);
2095
2096     /* We may need to schedule the pipe if this was the head of the pipe */
2097     if (!transaction->prev)
2098         __cvmx_usb_schedule(usb, 0);
2099
2100     CVMX_USB_RETURN(submit_handle);
2101 }
2102
2103
2104 /**
2105  * Call to submit a USB Bulk transfer to a pipe.
2106  *
2107  * @param state     USB device state populated by
2108  *                  cvmx_usb_initialize().
2109  * @param pipe_handle
2110  *                  Handle to the pipe for the transfer.
2111  * @param buffer    Physical address of the data buffer in
2112  *                  memory. Note that this is NOT A POINTER, but
2113  *                  the full 64bit physical address of the
2114  *                  buffer. This may be zero if buffer_length is
2115  *                  zero.
2116  * @param buffer_length
2117  *                  Length of buffer in bytes.
2118  * @param callback  Function to call when this transaction
2119  *                  completes. If the return value of this
2120  *                  function isn't an error, then this function
2121  *                  is guaranteed to be called when the
2122  *                  transaction completes. If this parameter is
2123  *                  NULL, then the generic callback registered
2124  *                  through cvmx_usb_register_callback is
2125  *                  called. If both are NULL, then there is no
2126  *                  way to know when a transaction completes.
2127  * @param user_data User supplied data returned when the
2128  *                  callback is called. This is only used if
2129  *                  callback in not NULL.
2130  *
2131  * @return A submitted transaction handle or negative on
2132  *         failure. Negative values are failure codes from
2133  *         cvmx_usb_status_t.
2134  */
2135 int cvmx_usb_submit_bulk(cvmx_usb_state_t *state, int pipe_handle,
2136                                 uint64_t buffer, int buffer_length,
2137                                 cvmx_usb_callback_func_t callback,
2138                                 void *user_data)
2139 {
2140     int submit_handle;
2141     cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
2142
2143     CVMX_USB_LOG_CALLED();
2144     CVMX_USB_LOG_PARAM("%p", state);
2145     CVMX_USB_LOG_PARAM("%d", pipe_handle);
2146     CVMX_USB_LOG_PARAM("0x%llx", (unsigned long long)buffer);
2147     CVMX_USB_LOG_PARAM("%d", buffer_length);
2148
2149     /* Pipe handle checking is done later in a common place */
2150     if (cvmx_unlikely(!buffer))
2151         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2152     if (cvmx_unlikely(buffer_length < 0))
2153         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2154     if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEVICE_MODE))
2155         CVMX_USB_RETURN(CVMX_USB_INCORRECT_MODE);
2156
2157     submit_handle = __cvmx_usb_submit_transaction(usb, pipe_handle,
2158                                          CVMX_USB_TRANSFER_BULK,
2159                                          0, /* flags */
2160                                          buffer,
2161                                          buffer_length,
2162                                          0, /* control_header */
2163                                          0, /* iso_start_frame */
2164                                          0, /* iso_number_packets */
2165                                          NULL, /* iso_packets */
2166                                          callback,
2167                                          user_data);
2168     CVMX_USB_RETURN(submit_handle);
2169 }
2170
2171
2172 /**
2173  * Call to submit a USB Interrupt transfer to a pipe.
2174  *
2175  * @param state     USB device state populated by
2176  *                  cvmx_usb_initialize().
2177  * @param pipe_handle
2178  *                  Handle to the pipe for the transfer.
2179  * @param buffer    Physical address of the data buffer in
2180  *                  memory. Note that this is NOT A POINTER, but
2181  *                  the full 64bit physical address of the
2182  *                  buffer. This may be zero if buffer_length is
2183  *                  zero.
2184  * @param buffer_length
2185  *                  Length of buffer in bytes.
2186  * @param callback  Function to call when this transaction
2187  *                  completes. If the return value of this
2188  *                  function isn't an error, then this function
2189  *                  is guaranteed to be called when the
2190  *                  transaction completes. If this parameter is
2191  *                  NULL, then the generic callback registered
2192  *                  through cvmx_usb_register_callback is
2193  *                  called. If both are NULL, then there is no
2194  *                  way to know when a transaction completes.
2195  * @param user_data User supplied data returned when the
2196  *                  callback is called. This is only used if
2197  *                  callback in not NULL.
2198  *
2199  * @return A submitted transaction handle or negative on
2200  *         failure. Negative values are failure codes from
2201  *         cvmx_usb_status_t.
2202  */
2203 int cvmx_usb_submit_interrupt(cvmx_usb_state_t *state, int pipe_handle,
2204                               uint64_t buffer, int buffer_length,
2205                               cvmx_usb_callback_func_t callback,
2206                               void *user_data)
2207 {
2208     int submit_handle;
2209     cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
2210
2211     CVMX_USB_LOG_CALLED();
2212     CVMX_USB_LOG_PARAM("%p", state);
2213     CVMX_USB_LOG_PARAM("%d", pipe_handle);
2214     CVMX_USB_LOG_PARAM("0x%llx", (unsigned long long)buffer);
2215     CVMX_USB_LOG_PARAM("%d", buffer_length);
2216
2217     /* Pipe handle checking is done later in a common place */
2218     if (cvmx_unlikely(!buffer))
2219         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2220     if (cvmx_unlikely(buffer_length < 0))
2221         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2222     if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEVICE_MODE))
2223         CVMX_USB_RETURN(CVMX_USB_INCORRECT_MODE);
2224
2225     submit_handle = __cvmx_usb_submit_transaction(usb, pipe_handle,
2226                                          CVMX_USB_TRANSFER_INTERRUPT,
2227                                          0, /* flags */
2228                                          buffer,
2229                                          buffer_length,
2230                                          0, /* control_header */
2231                                          0, /* iso_start_frame */
2232                                          0, /* iso_number_packets */
2233                                          NULL, /* iso_packets */
2234                                          callback,
2235                                          user_data);
2236     CVMX_USB_RETURN(submit_handle);
2237 }
2238
2239
2240 /**
2241  * Call to submit a USB Control transfer to a pipe.
2242  *
2243  * @param state     USB device state populated by
2244  *                  cvmx_usb_initialize().
2245  * @param pipe_handle
2246  *                  Handle to the pipe for the transfer.
2247  * @param control_header
2248  *                  USB 8 byte control header physical address.
2249  *                  Note that this is NOT A POINTER, but the
2250  *                  full 64bit physical address of the buffer.
2251  * @param buffer    Physical address of the data buffer in
2252  *                  memory. Note that this is NOT A POINTER, but
2253  *                  the full 64bit physical address of the
2254  *                  buffer. This may be zero if buffer_length is
2255  *                  zero.
2256  * @param buffer_length
2257  *                  Length of buffer in bytes.
2258  * @param callback  Function to call when this transaction
2259  *                  completes. If the return value of this
2260  *                  function isn't an error, then this function
2261  *                  is guaranteed to be called when the
2262  *                  transaction completes. If this parameter is
2263  *                  NULL, then the generic callback registered
2264  *                  through cvmx_usb_register_callback is
2265  *                  called. If both are NULL, then there is no
2266  *                  way to know when a transaction completes.
2267  * @param user_data User supplied data returned when the
2268  *                  callback is called. This is only used if
2269  *                  callback in not NULL.
2270  *
2271  * @return A submitted transaction handle or negative on
2272  *         failure. Negative values are failure codes from
2273  *         cvmx_usb_status_t.
2274  */
2275 int cvmx_usb_submit_control(cvmx_usb_state_t *state, int pipe_handle,
2276                             uint64_t control_header,
2277                             uint64_t buffer, int buffer_length,
2278                             cvmx_usb_callback_func_t callback,
2279                             void *user_data)
2280 {
2281     int submit_handle;
2282     cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
2283     cvmx_usb_control_header_t *header = cvmx_phys_to_ptr(control_header);
2284
2285     CVMX_USB_LOG_CALLED();
2286     CVMX_USB_LOG_PARAM("%p", state);
2287     CVMX_USB_LOG_PARAM("%d", pipe_handle);
2288     CVMX_USB_LOG_PARAM("0x%llx", (unsigned long long)control_header);
2289     CVMX_USB_LOG_PARAM("0x%llx", (unsigned long long)buffer);
2290     CVMX_USB_LOG_PARAM("%d", buffer_length);
2291
2292     /* Pipe handle checking is done later in a common place */
2293     if (cvmx_unlikely(!control_header))
2294         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2295     /* Some drivers send a buffer with a zero length. God only knows why */
2296     if (cvmx_unlikely(buffer && (buffer_length < 0)))
2297         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2298     if (cvmx_unlikely(!buffer && (buffer_length != 0)))
2299         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2300     if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEVICE_MODE))
2301         CVMX_USB_RETURN(CVMX_USB_INCORRECT_MODE);
2302     if ((header->s.request_type & 0x80) == 0)
2303         buffer_length = cvmx_le16_to_cpu(header->s.length);
2304
2305     submit_handle = __cvmx_usb_submit_transaction(usb, pipe_handle,
2306                                          CVMX_USB_TRANSFER_CONTROL,
2307                                          0, /* flags */
2308                                          buffer,
2309                                          buffer_length,
2310                                          control_header,
2311                                          0, /* iso_start_frame */
2312                                          0, /* iso_number_packets */
2313                                          NULL, /* iso_packets */
2314                                          callback,
2315                                          user_data);
2316     CVMX_USB_RETURN(submit_handle);
2317 }
2318
2319
2320 /**
2321  * Call to submit a USB Isochronous transfer to a pipe.
2322  *
2323  * @param state     USB device state populated by
2324  *                  cvmx_usb_initialize().
2325  * @param pipe_handle
2326  *                  Handle to the pipe for the transfer.
2327  * @param start_frame
2328  *                  Number of frames into the future to schedule
2329  *                  this transaction.
2330  * @param flags     Flags to control the transfer. See
2331  *                  cvmx_usb_isochronous_flags_t for the flag
2332  *                  definitions.
2333  * @param number_packets
2334  *                  Number of sequential packets to transfer.
2335  *                  "packets" is a pointer to an array of this
2336  *                  many packet structures.
2337  * @param packets   Description of each transfer packet as
2338  *                  defined by cvmx_usb_iso_packet_t. The array
2339  *                  pointed to here must stay valid until the
2340  *                  complete callback is called.
2341  * @param buffer    Physical address of the data buffer in
2342  *                  memory. Note that this is NOT A POINTER, but
2343  *                  the full 64bit physical address of the
2344  *                  buffer. This may be zero if buffer_length is
2345  *                  zero.
2346  * @param buffer_length
2347  *                  Length of buffer in bytes.
2348  * @param callback  Function to call when this transaction
2349  *                  completes. If the return value of this
2350  *                  function isn't an error, then this function
2351  *                  is guaranteed to be called when the
2352  *                  transaction completes. If this parameter is
2353  *                  NULL, then the generic callback registered
2354  *                  through cvmx_usb_register_callback is
2355  *                  called. If both are NULL, then there is no
2356  *                  way to know when a transaction completes.
2357  * @param user_data User supplied data returned when the
2358  *                  callback is called. This is only used if
2359  *                  callback in not NULL.
2360  *
2361  * @return A submitted transaction handle or negative on
2362  *         failure. Negative values are failure codes from
2363  *         cvmx_usb_status_t.
2364  */
2365 int cvmx_usb_submit_isochronous(cvmx_usb_state_t *state, int pipe_handle,
2366                                 int start_frame, int flags,
2367                                 int number_packets,
2368                                 cvmx_usb_iso_packet_t packets[],
2369                                 uint64_t buffer, int buffer_length,
2370                                 cvmx_usb_callback_func_t callback,
2371                                 void *user_data)
2372 {
2373     int submit_handle;
2374     cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
2375
2376     CVMX_USB_LOG_CALLED();
2377     CVMX_USB_LOG_PARAM("%p", state);
2378     CVMX_USB_LOG_PARAM("%d", pipe_handle);
2379     CVMX_USB_LOG_PARAM("%d", start_frame);
2380     CVMX_USB_LOG_PARAM("0x%x", flags);
2381     CVMX_USB_LOG_PARAM("%d", number_packets);
2382     CVMX_USB_LOG_PARAM("%p", packets);
2383     CVMX_USB_LOG_PARAM("0x%llx", (unsigned long long)buffer);
2384     CVMX_USB_LOG_PARAM("%d", buffer_length);
2385
2386     /* Pipe handle checking is done later in a common place */
2387     if (cvmx_unlikely(start_frame < 0))
2388         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2389     if (cvmx_unlikely(flags & ~(CVMX_USB_ISOCHRONOUS_FLAGS_ALLOW_SHORT | CVMX_USB_ISOCHRONOUS_FLAGS_ASAP)))
2390         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2391     if (cvmx_unlikely(number_packets < 1))
2392         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2393     if (cvmx_unlikely(!packets))
2394         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2395     if (cvmx_unlikely(!buffer))
2396         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2397     if (cvmx_unlikely(buffer_length < 0))
2398         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2399     if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEVICE_MODE))
2400         CVMX_USB_RETURN(CVMX_USB_INCORRECT_MODE);
2401
2402     submit_handle = __cvmx_usb_submit_transaction(usb, pipe_handle,
2403                                          CVMX_USB_TRANSFER_ISOCHRONOUS,
2404                                          flags,
2405                                          buffer,
2406                                          buffer_length,
2407                                          0, /* control_header */
2408                                          start_frame,
2409                                          number_packets,
2410                                          packets,
2411                                          callback,
2412                                          user_data);
2413     CVMX_USB_RETURN(submit_handle);
2414 }
2415
2416
2417 /**
2418  * Cancel one outstanding request in a pipe. Canceling a request
2419  * can fail if the transaction has already completed before cancel
2420  * is called. Even after a successful cancel call, it may take
2421  * a frame or two for the cvmx_usb_poll() function to call the
2422  * associated callback.
2423  *
2424  * @param state  USB device state populated by
2425  *               cvmx_usb_initialize().
2426  * @param pipe_handle
2427  *               Pipe handle to cancel requests in.
2428  * @param submit_handle
2429  *               Handle to transaction to cancel, returned by the submit function.
2430  *
2431  * @return CVMX_USB_SUCCESS or a negative error code defined in
2432  *         cvmx_usb_status_t.
2433  */
2434 cvmx_usb_status_t cvmx_usb_cancel(cvmx_usb_state_t *state, int pipe_handle,
2435                                   int submit_handle)
2436 {
2437     cvmx_usb_transaction_t *transaction;
2438     cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
2439     cvmx_usb_pipe_t *pipe = usb->pipe + pipe_handle;
2440
2441     CVMX_USB_LOG_CALLED();
2442     CVMX_USB_LOG_PARAM("%p", state);
2443     CVMX_USB_LOG_PARAM("%d", pipe_handle);
2444     CVMX_USB_LOG_PARAM("%d", submit_handle);
2445
2446     if (cvmx_unlikely((pipe_handle < 0) || (pipe_handle >= MAX_PIPES)))
2447         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2448     if (cvmx_unlikely((submit_handle < 0) || (submit_handle >= MAX_TRANSACTIONS)))
2449         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2450     if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEVICE_MODE))
2451         CVMX_USB_RETURN(CVMX_USB_INCORRECT_MODE);
2452
2453     /* Fail if the pipe isn't open */
2454     if (cvmx_unlikely((pipe->flags & __CVMX_USB_PIPE_FLAGS_OPEN) == 0))
2455         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2456
2457     transaction = usb->transaction + submit_handle;
2458
2459     /* Fail if this transaction already completed */
2460     if (cvmx_unlikely((transaction->flags & __CVMX_USB_TRANSACTION_FLAGS_IN_USE) == 0))
2461         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2462
2463     /* If the transaction is the HEAD of the queue and scheduled. We need to
2464         treat it special */
2465     if ((pipe->head == transaction) &&
2466         (pipe->flags & __CVMX_USB_PIPE_FLAGS_SCHEDULED))
2467     {
2468         cvmx_usbcx_hccharx_t usbc_hcchar;
2469
2470         usb->pipe_for_channel[pipe->channel] = NULL;
2471         pipe->flags &= ~__CVMX_USB_PIPE_FLAGS_SCHEDULED;
2472
2473         CVMX_SYNCW;
2474
2475         usbc_hcchar.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCCHARX(pipe->channel, usb->index));
2476         /* If the channel isn't enabled then the transaction already completed */
2477         if (usbc_hcchar.s.chena)
2478         {
2479             usbc_hcchar.s.chdis = 1;
2480             __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCCHARX(pipe->channel, usb->index), usbc_hcchar.u32);
2481         }
2482     }
2483     __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_CANCEL);
2484     CVMX_USB_RETURN(CVMX_USB_SUCCESS);
2485 }
2486
2487
2488 /**
2489  * Cancel all outstanding requests in a pipe. Logically all this
2490  * does is call cvmx_usb_cancel() in a loop.
2491  *
2492  * @param state  USB device state populated by
2493  *               cvmx_usb_initialize().
2494  * @param pipe_handle
2495  *               Pipe handle to cancel requests in.
2496  *
2497  * @return CVMX_USB_SUCCESS or a negative error code defined in
2498  *         cvmx_usb_status_t.
2499  */
2500 cvmx_usb_status_t cvmx_usb_cancel_all(cvmx_usb_state_t *state, int pipe_handle)
2501 {
2502     cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
2503     cvmx_usb_pipe_t *pipe = usb->pipe + pipe_handle;
2504
2505     CVMX_USB_LOG_CALLED();
2506     CVMX_USB_LOG_PARAM("%p", state);
2507     CVMX_USB_LOG_PARAM("%d", pipe_handle);
2508     if (cvmx_unlikely((pipe_handle < 0) || (pipe_handle >= MAX_PIPES)))
2509         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2510     if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEVICE_MODE))
2511         CVMX_USB_RETURN(CVMX_USB_INCORRECT_MODE);
2512
2513     /* Fail if the pipe isn't open */
2514     if (cvmx_unlikely((pipe->flags & __CVMX_USB_PIPE_FLAGS_OPEN) == 0))
2515         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2516
2517     /* Simply loop through and attempt to cancel each transaction */
2518     while (pipe->head)
2519     {
2520         cvmx_usb_status_t result = cvmx_usb_cancel(state, pipe_handle,
2521             __cvmx_usb_get_submit_handle(usb, pipe->head));
2522         if (cvmx_unlikely(result != CVMX_USB_SUCCESS))
2523             CVMX_USB_RETURN(result);
2524     }
2525     CVMX_USB_RETURN(CVMX_USB_SUCCESS);
2526 }
2527
2528
2529 /**
2530  * Close a pipe created with cvmx_usb_open_pipe().
2531  *
2532  * @param state  USB device state populated by
2533  *               cvmx_usb_initialize().
2534  * @param pipe_handle
2535  *               Pipe handle to close.
2536  *
2537  * @return CVMX_USB_SUCCESS or a negative error code defined in
2538  *         cvmx_usb_status_t. CVMX_USB_BUSY is returned if the
2539  *         pipe has outstanding transfers.
2540  */
2541 cvmx_usb_status_t cvmx_usb_close_pipe(cvmx_usb_state_t *state, int pipe_handle)
2542 {
2543     cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
2544     cvmx_usb_pipe_t *pipe = usb->pipe + pipe_handle;
2545
2546     CVMX_USB_LOG_CALLED();
2547     CVMX_USB_LOG_PARAM("%p", state);
2548     CVMX_USB_LOG_PARAM("%d", pipe_handle);
2549     if (cvmx_unlikely((pipe_handle < 0) || (pipe_handle >= MAX_PIPES)))
2550         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2551     if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEVICE_MODE))
2552         CVMX_USB_RETURN(CVMX_USB_INCORRECT_MODE);
2553
2554     /* Fail if the pipe isn't open */
2555     if (cvmx_unlikely((pipe->flags & __CVMX_USB_PIPE_FLAGS_OPEN) == 0))
2556         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2557
2558     /* Fail if the pipe has pending transactions */
2559     if (cvmx_unlikely(pipe->head))
2560         CVMX_USB_RETURN(CVMX_USB_BUSY);
2561
2562     pipe->flags = 0;
2563     __cvmx_usb_remove_pipe(&usb->idle_pipes, pipe);
2564     __cvmx_usb_append_pipe(&usb->free_pipes, pipe);
2565
2566     CVMX_USB_RETURN(CVMX_USB_SUCCESS);
2567 }
2568
2569
2570 /**
2571  * Register a function to be called when various USB events occur.
2572  *
2573  * @param state     USB device state populated by
2574  *                  cvmx_usb_initialize().
2575  * @param reason    Which event to register for.
2576  * @param callback  Function to call when the event occurs.
2577  * @param user_data User data parameter to the function.
2578  *
2579  * @return CVMX_USB_SUCCESS or a negative error code defined in
2580  *         cvmx_usb_status_t.
2581  */
2582 cvmx_usb_status_t cvmx_usb_register_callback(cvmx_usb_state_t *state,
2583                                              cvmx_usb_callback_t reason,
2584                                              cvmx_usb_callback_func_t callback,
2585                                              void *user_data)
2586 {
2587     cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
2588
2589     CVMX_USB_LOG_CALLED();
2590     CVMX_USB_LOG_PARAM("%p", state);
2591     CVMX_USB_LOG_PARAM("%d", reason);
2592     CVMX_USB_LOG_PARAM("%p", callback);
2593     CVMX_USB_LOG_PARAM("%p", user_data);
2594     if (cvmx_unlikely(reason >= __CVMX_USB_CALLBACK_END))
2595         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2596     if (cvmx_unlikely(!callback))
2597         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2598
2599     usb->callback[reason] = callback;
2600     usb->callback_data[reason] = user_data;
2601
2602     CVMX_USB_RETURN(CVMX_USB_SUCCESS);
2603 }
2604
2605
2606 /**
2607  * Get the current USB protocol level frame number. The frame
2608  * number is always in the range of 0-0x7ff.
2609  *
2610  * @param state  USB device state populated by
2611  *               cvmx_usb_initialize().
2612  *
2613  * @return USB frame number
2614  */
2615 int cvmx_usb_get_frame_number(cvmx_usb_state_t *state)
2616 {
2617     int frame_number;
2618     cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
2619
2620     CVMX_USB_LOG_CALLED();
2621     CVMX_USB_LOG_PARAM("%p", state);
2622
2623     if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEVICE_MODE))
2624     {
2625         cvmx_usbcx_dsts_t usbc_dsts;
2626         usbc_dsts.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_DSTS(usb->index));
2627         frame_number = usbc_dsts.s.soffn;
2628     }
2629     else
2630     {
2631         cvmx_usbcx_hfnum_t usbc_hfnum;
2632         usbc_hfnum.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index));
2633         frame_number = usbc_hfnum.s.frnum;
2634     }
2635
2636     CVMX_USB_RETURN(frame_number);
2637 }
2638
2639
2640 /**
2641  * @INTERNAL
2642  * Poll a channel for status
2643  *
2644  * @param usb     USB device
2645  * @param channel Channel to poll
2646  *
2647  * @return Zero on success
2648  */
2649 static int __cvmx_usb_poll_channel(cvmx_usb_internal_state_t *usb, int channel)
2650 {
2651     cvmx_usbcx_hcintx_t usbc_hcint;
2652     cvmx_usbcx_hctsizx_t usbc_hctsiz;
2653     cvmx_usbcx_hccharx_t usbc_hcchar;
2654     cvmx_usb_pipe_t *pipe;
2655     cvmx_usb_transaction_t *transaction;
2656     int bytes_this_transfer;
2657     int bytes_in_last_packet;
2658     int packets_processed;
2659     int buffer_space_left;
2660     CVMX_USB_LOG_CALLED();
2661     CVMX_USB_LOG_PARAM("%p", usb);
2662     CVMX_USB_LOG_PARAM("%d", channel);
2663
2664     /* Read the interrupt status bits for the channel */
2665     usbc_hcint.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCINTX(channel, usb->index));
2666
2667     /* We ignore any interrupts where the channel hasn't halted yet. These
2668         should be impossible since we don't enable any interrupts except for
2669         channel halted */
2670     if (!usbc_hcint.s.chhltd)
2671         CVMX_USB_RETURN(0);
2672
2673     /* Now that the channel has halted, clear all status bits before
2674         processing. This way we don't have any race conditions caused by the
2675         channel starting up and finishing before we clear the bits */
2676     __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTX(channel, usb->index), usbc_hcint.u32);
2677     //cvmx_csr_db_decode(cvmx_get_proc_id(), CVMX_USBCX_HCINTX(channel, usb->index), usbc_hcint.u32);
2678
2679     usb->idle_hardware_channels |= (1<<channel);
2680
2681     /* Make sure this channel is tied to a valid pipe */
2682     pipe = usb->pipe_for_channel[channel];
2683     CVMX_PREFETCH(pipe, 0);
2684     CVMX_PREFETCH(pipe, 128);
2685     if (!pipe)
2686         CVMX_USB_RETURN(0);
2687     transaction = pipe->head;
2688     CVMX_PREFETCH0(transaction);
2689
2690     /* Disconnect this pipe from the HW channel. Later the schedule function will
2691         figure out which pipe needs to go */
2692     usb->pipe_for_channel[channel] = NULL;
2693     pipe->flags &= ~__CVMX_USB_PIPE_FLAGS_SCHEDULED;
2694
2695     /* Read the channel config info so we can figure out how much data
2696         transfered */
2697     usbc_hcchar.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index));
2698     usbc_hctsiz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index));
2699
2700     /* Calculating the number of bytes successfully transfered is dependent on
2701         the transfer direction */
2702     packets_processed = transaction->pktcnt - usbc_hctsiz.s.pktcnt;
2703     if (usbc_hcchar.s.epdir)
2704     {
2705         /* IN transactions are easy. For every byte received the hardware
2706             decrements xfersize. All we need to do is subtract the current
2707             value of xfersize from its starting value and we know how many
2708             bytes were written to the buffer */
2709         bytes_this_transfer = transaction->xfersize - usbc_hctsiz.s.xfersize;
2710     }
2711     else
2712     {
2713         /* OUT transaction don't decrement xfersize. Instead pktcnt is
2714             decremented on every successful packet send. The hardware does
2715             this when it receives an ACK, or NYET. If it doesn't
2716             receive one of these responses pktcnt doesn't change */
2717         bytes_this_transfer = packets_processed * usbc_hcchar.s.mps;
2718         /* The last packet may not be a full transfer if we didn't have
2719             enough data */
2720         if (bytes_this_transfer > transaction->xfersize)
2721             bytes_this_transfer = transaction->xfersize;
2722     }
2723     /* Figure out how many bytes were in the last packet of the transfer */
2724     if (packets_processed)
2725         bytes_in_last_packet = bytes_this_transfer - (packets_processed-1) * usbc_hcchar.s.mps;
2726     else
2727         bytes_in_last_packet = bytes_this_transfer;
2728
2729     /* As a special case, setup transactions output the setup header, not
2730         the user's data. For this reason we don't count setup data as bytes
2731         transfered */
2732     if ((transaction->stage == CVMX_USB_STAGE_SETUP) ||
2733         (transaction->stage == CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE))
2734         bytes_this_transfer = 0;
2735
2736     /* Optional debug output */
2737     if (cvmx_unlikely((usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_TRANSFERS) ||
2738         (pipe->flags & CVMX_USB_PIPE_FLAGS_DEBUG_TRANSFERS)))
2739         cvmx_dprintf("%s: Channel %d halted. Pipe %d transaction %d stage %d bytes=%d\n",
2740                      __FUNCTION__, channel,
2741                      __cvmx_usb_get_pipe_handle(usb, pipe),
2742                      __cvmx_usb_get_submit_handle(usb, transaction),
2743                      transaction->stage, bytes_this_transfer);
2744
2745     /* Add the bytes transfered to the running total. It is important that
2746         bytes_this_transfer doesn't count any data that needs to be
2747         retransmitted */
2748     transaction->actual_bytes += bytes_this_transfer;
2749     if (transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS)
2750         buffer_space_left = transaction->iso_packets[0].length - transaction->actual_bytes;
2751     else
2752         buffer_space_left = transaction->buffer_length - transaction->actual_bytes;
2753
2754     /* We need to remember the PID toggle state for the next transaction. The
2755         hardware already updated it for the next transaction */
2756     pipe->pid_toggle = !(usbc_hctsiz.s.pid == 0);
2757
2758     /* For high speed bulk out, assume the next transaction will need to do a
2759         ping before proceeding. If this isn't true the ACK processing below
2760         will clear this flag */
2761     if ((pipe->device_speed == CVMX_USB_SPEED_HIGH) &&
2762         (pipe->transfer_type == CVMX_USB_TRANSFER_BULK) &&
2763         (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT))
2764         pipe->flags |= __CVMX_USB_PIPE_FLAGS_NEED_PING;
2765
2766     if (usbc_hcint.s.stall)
2767     {
2768         /* STALL as a response means this transaction cannot be completed
2769             because the device can't process transactions. Tell the user. Any
2770             data that was transfered will be counted on the actual bytes
2771             transfered */
2772         pipe->pid_toggle = 0;
2773         __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_STALL);
2774     }
2775     else if (0 && usbc_hcint.s.xfercompl)
2776     {
2777         /* XferCompl is only useful in non DMA mode */
2778     }
2779     else if (usbc_hcint.s.xacterr)
2780     {
2781         /* We know at least one packet worked if we get a ACK or NAK. Reset the retry counter */
2782         if (usbc_hcint.s.nak || usbc_hcint.s.ack)
2783             transaction->retries = 0;
2784         transaction->retries++;
2785         if (transaction->retries > MAX_RETRIES)
2786         {
2787             /* XactErr as a response means the device signaled something wrong with
2788                 the transfer. For example, PID toggle errors cause these */
2789             __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_XACTERR);
2790         }
2791         else
2792         {
2793             /* Rewind to the beginning of the transaction by anding off the
2794                 split complete bit */
2795             transaction->stage &= ~1;
2796             pipe->split_sc_frame = -1;
2797             pipe->next_tx_cycle = cvmx_read64_uint64(CVMX_IPD_CLK_COUNT) + pipe->interval;
2798         }
2799     }
2800     else if (0 && usbc_hcint.s.datatglerr)
2801     {
2802         /* The hardware automatically handles Data Toggle Errors for us */
2803     }
2804     else if (usbc_hcint.s.bblerr)
2805     {
2806         /* Babble Error (BblErr) */
2807         __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_BABBLEERR);
2808     }
2809     else if (usbc_hcint.s.frmovrun)
2810     {
2811         /* Frame Overrun (FrmOvrun) */
2812         /* Rewind to the beginning of the transaction by anding off the
2813             split complete bit */
2814         transaction->stage &= ~1;
2815         pipe->split_sc_frame = -1;
2816     }
2817     else if (usbc_hcint.s.nyet)
2818     {
2819         /* NYET as a response is only allowed in three cases: as a response to
2820             a ping, as a response to a split transaction, and as a response to
2821             a bulk out. The ping case is handled by hardware, so we only have
2822             splits and bulk out */
2823         if (!__cvmx_usb_pipe_needs_split(usb, pipe))
2824         {
2825             transaction->retries = 0;
2826             /* If there is more data to go then we need to try again. Otherwise
2827                 this transaction is complete */
2828             if ((buffer_space_left == 0) || (bytes_in_last_packet < pipe->max_packet))
2829                 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
2830         }
2831         else
2832         {
2833             /* Split transactions retry the split complete 4 times then rewind
2834                 to the start split and do the entire transactions again */
2835             transaction->retries++;
2836             if ((transaction->retries & 0x3) == 0)
2837             {
2838                 /* Rewind to the beginning of the transaction by anding off the
2839                     split complete bit */
2840                 transaction->stage &= ~1;
2841                 pipe->split_sc_frame = -1;
2842             }
2843         }
2844     }
2845     else if (usbc_hcint.s.ack)
2846     {
2847         transaction->retries = 0;
2848         /* The ACK bit can only be checked after the other error bits. This is
2849             because a multi packet transfer may succeed in a number of packets
2850             and then get a different response on the last packet. In this case
2851             both ACK and the last response bit will be set. If none of the
2852             other response bits is set, then the last packet must have been an
2853             ACK */
2854
2855         /* Since we got an ACK, we know we don't need to do a ping on this
2856             pipe */
2857         pipe->flags &= ~__CVMX_USB_PIPE_FLAGS_NEED_PING;
2858
2859         switch (transaction->type)
2860         {
2861             case CVMX_USB_TRANSFER_CONTROL:
2862                 switch (transaction->stage)
2863                 {
2864                     case CVMX_USB_STAGE_NON_CONTROL:
2865                     case CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE:
2866                         /* This should be impossible */
2867                         __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_ERROR);
2868                         break;
2869                     case CVMX_USB_STAGE_SETUP:
2870                         pipe->pid_toggle = 1;
2871                         if (__cvmx_usb_pipe_needs_split(usb, pipe))
2872                             transaction->stage = CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE;
2873                         else
2874                         {
2875                             cvmx_usb_control_header_t *header = cvmx_phys_to_ptr(transaction->control_header);
2876                             if (header->s.length)
2877                                 transaction->stage = CVMX_USB_STAGE_DATA;
2878                             else
2879                                 transaction->stage = CVMX_USB_STAGE_STATUS;
2880                         }
2881                         break;
2882                     case CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE:
2883                         {
2884                             cvmx_usb_control_header_t *header = cvmx_phys_to_ptr(transaction->control_header);
2885                             if (header->s.length)
2886                                 transaction->stage = CVMX_USB_STAGE_DATA;
2887                             else
2888                                 transaction->stage = CVMX_USB_STAGE_STATUS;
2889                         }
2890                         break;
2891                     case CVMX_USB_STAGE_DATA:
2892                         if (__cvmx_usb_pipe_needs_split(usb, pipe))
2893                             transaction->stage = CVMX_USB_STAGE_DATA_SPLIT_COMPLETE;
2894                         else if ((buffer_space_left == 0) || (bytes_in_last_packet < pipe->max_packet))
2895                         {
2896                             pipe->pid_toggle = 1;
2897                             transaction->stage = CVMX_USB_STAGE_STATUS;
2898                         }
2899                         break;
2900                     case CVMX_USB_STAGE_DATA_SPLIT_COMPLETE:
2901                         if ((buffer_space_left == 0) || (bytes_in_last_packet < pipe->max_packet))
2902                         {
2903                             pipe->pid_toggle = 1;
2904                             transaction->stage = CVMX_USB_STAGE_STATUS;
2905                         }
2906                         else
2907                         {
2908                             transaction->stage = CVMX_USB_STAGE_DATA;
2909                         }
2910                         break;
2911                     case CVMX_USB_STAGE_STATUS:
2912                         if (__cvmx_usb_pipe_needs_split(usb, pipe))
2913                             transaction->stage = CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE;
2914                         else
2915                             __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
2916                         break;
2917                     case CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE:
2918                         __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
2919                         break;
2920                 }
2921                 break;
2922             case CVMX_USB_TRANSFER_BULK:
2923             case CVMX_USB_TRANSFER_INTERRUPT:
2924                 /* The only time a bulk transfer isn't complete when
2925                     it finishes with an ACK is during a split transaction. For
2926                     splits we need to continue the transfer if more data is
2927                     needed */
2928                 if (__cvmx_usb_pipe_needs_split(usb, pipe))
2929                 {
2930                     if (transaction->stage == CVMX_USB_STAGE_NON_CONTROL)
2931                         transaction->stage = CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE;
2932                     else
2933                     {
2934                         if (buffer_space_left && (bytes_in_last_packet == pipe->max_packet))
2935                             transaction->stage = CVMX_USB_STAGE_NON_CONTROL;
2936                         else
2937                         {
2938                             if (transaction->type == CVMX_USB_TRANSFER_INTERRUPT)
2939                                 pipe->next_tx_cycle += pipe->interval;
2940                             __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
2941                         }
2942                     }
2943                 }
2944                 else
2945                 {
2946                     if ((pipe->device_speed == CVMX_USB_SPEED_HIGH) &&
2947                         (pipe->transfer_type == CVMX_USB_TRANSFER_BULK) &&
2948                         (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) &&
2949                         (usbc_hcint.s.nak))
2950                         pipe->flags |= __CVMX_USB_PIPE_FLAGS_NEED_PING;
2951                     if (!buffer_space_left || (bytes_in_last_packet < pipe->max_packet))
2952                     {
2953                         if (transaction->type == CVMX_USB_TRANSFER_INTERRUPT)
2954                             pipe->next_tx_cycle += pipe->interval;
2955                         __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
2956                     }
2957                 }
2958                 break;
2959             case CVMX_USB_TRANSFER_ISOCHRONOUS:
2960                 if (__cvmx_usb_pipe_needs_split(usb, pipe))
2961                 {
2962                     /* ISOCHRONOUS OUT splits don't require a complete split stage.
2963                         Instead they use a sequence of begin OUT splits to transfer
2964                         the data 188 bytes at a time. Once the transfer is complete,
2965                         the pipe sleeps until the next schedule interval */
2966                     if (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT)
2967                     {
2968                         pipe->next_tx_cycle += pipe->interval;
2969                         /* If no space left or this wasn't a max size packet then
2970                             this transfer is complete. Otherwise start it again
2971                             to send the next 188 bytes */
2972                         if (!buffer_space_left || (bytes_this_transfer < 188))
2973                             __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
2974                     }
2975                     else
2976                     {
2977                         if (transaction->stage == CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE)
2978                         {
2979                             /* We are in the incomming data phase. Keep getting
2980                                 data until we run out of space or get a small
2981                                 packet */
2982                             if ((buffer_space_left == 0) || (bytes_in_last_packet < pipe->max_packet))
2983                             {
2984                                 pipe->next_tx_cycle += pipe->interval;
2985                                 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
2986                             }
2987                         }
2988                         else
2989                             transaction->stage = CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE;
2990                     }
2991                 }
2992                 else
2993                 {
2994                     pipe->next_tx_cycle += pipe->interval;
2995                     __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
2996                 }
2997                 break;
2998         }
2999     }
3000     else if (usbc_hcint.s.nak)
3001     {
3002         uint64_t ipd_clk_count;
3003         /* NAK as a response means the device couldn't accept the transaction,
3004             but it should be retried in the future. Rewind to the beginning of
3005             the transaction by anding off the split complete bit. Retry in the
3006             next interval */
3007         transaction->retries = 0;
3008         transaction->stage &= ~1;
3009         pipe->next_tx_cycle += pipe->interval;
3010         ipd_clk_count = cvmx_read64_uint64(CVMX_IPD_CLK_COUNT);
3011         if (pipe->next_tx_cycle < ipd_clk_count)
3012             pipe->next_tx_cycle = ipd_clk_count + pipe->interval;
3013     }
3014     else
3015     {
3016         /* We get channel halted interrupts with no result bits sets when the
3017             cable is unplugged */
3018         __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_ERROR);
3019     }
3020     CVMX_USB_RETURN(0);
3021 }
3022
3023
3024 /**
3025  * Poll a device mode endpoint for status
3026  *
3027  * @param usb    USB device state populated by
3028  *               cvmx_usb_initialize().
3029  * @param endpoint_num
3030  *               Endpoint to poll
3031  *
3032  * @return Zero on success
3033  */
3034 static int __cvmx_usb_poll_endpoint(cvmx_usb_internal_state_t *usb, int endpoint_num)
3035 {
3036     cvmx_usbcx_diepintx_t usbc_diepint;
3037     cvmx_usbcx_doepintx_t usbc_doepint;
3038
3039     CVMX_USB_LOG_CALLED();
3040     CVMX_USB_LOG_PARAM("%p", usb);
3041     CVMX_USB_LOG_PARAM("%d", endpoint_num);
3042
3043     usbc_diepint.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_DIEPINTX(endpoint_num, usb->index));
3044     __cvmx_usb_write_csr32(usb, CVMX_USBCX_DIEPINTX(endpoint_num, usb->index), usbc_diepint.u32);
3045     //cvmx_csr_db_decode(cvmx_get_proc_id(), CVMX_USBCX_DIEPINTX(endpoint_num, usb->index), usbc_diepint.u32);
3046     if (usbc_diepint.s.inepnakeff)
3047     {
3048         /* IN Endpoint NAK Effective (INEPNakEff)
3049             Applies to periodic IN endpoints only.
3050             Indicates that the IN endpoint NAK bit set by the application has
3051             taken effect in the core. This bit can be cleared when the
3052             application clears the IN endpoint NAK by writing to
3053             DIEPCTLn.CNAK.
3054             This interrupt indicates that the core has sampled the NAK bit
3055             set (either by the application or by the core).
3056             This interrupt does not necessarily mean that a NAK handshake
3057             is sent on the USB. A STALL bit takes priority over a NAK bit. */
3058         /* Nothing to do */
3059     }
3060     if (usbc_diepint.s.intknepmis)
3061     {
3062         /* IN Token Received with EP Mismatch (INTknEPMis)
3063             Applies to non-periodic IN endpoints only.
3064             Indicates that the data in the top of the non-periodic TxFIFO
3065             belongs to an endpoint other than the one for which the IN
3066             token was received. This interrupt is asserted on the endpoint
3067             for which the IN token was received. */
3068         if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO))
3069             cvmx_dprintf("%s: Endpoint %d mismatch\n", __FUNCTION__, endpoint_num);
3070     }
3071     if (usbc_diepint.s.intkntxfemp)
3072     {
3073         /* IN Token Received When TxFIFO is Empty (INTknTXFEmp)
3074             Applies only to non-periodic IN endpoints.
3075             Indicates that an IN token was received when the associated
3076             TxFIFO (periodic/non-periodic) was empty. This interrupt is
3077             asserted on the endpoint for which the IN token was received. */
3078         if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO))
3079             cvmx_dprintf("%s: Received IN token on endpoint %d without data\n", __FUNCTION__, endpoint_num);
3080     }
3081     if (usbc_diepint.s.timeout)
3082     {
3083         /* Timeout Condition (TimeOUT)
3084             Applies to non-isochronous IN endpoints only.
3085             Indicates that the core has detected a timeout condition on the
3086             USB for the last IN token on this endpoint. */
3087         if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO))
3088             cvmx_dprintf("%s: Received timeout on endpoint %d\n", __FUNCTION__, endpoint_num);
3089     }
3090     if (usbc_diepint.s.ahberr)
3091     {
3092         /* AHB Error (AHBErr)
3093             This is generated only in Internal DMA mode when there is an
3094             AHB error during an AHB read/write. The application can read
3095             the corresponding endpoint DMA address register to get the
3096             error address. */
3097         if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO))
3098             cvmx_dprintf("%s: AHB error on endpoint %d\n", __FUNCTION__, endpoint_num);
3099     }
3100     if (usbc_diepint.s.epdisbld)
3101     {
3102         /* Endpoint Disabled Interrupt (EPDisbld)
3103             This bit indicates that the endpoint is disabled per the
3104             application's request. */
3105         /* Nothing to do */
3106     }
3107     if (usbc_diepint.s.xfercompl)
3108     {
3109         /* Transfer Completed Interrupt (XferCompl)
3110             Indicates that the programmed transfer is complete on the AHB
3111             as well as on the USB, for this endpoint. */
3112         __cvmx_usb_perform_callback(usb, usb->pipe + endpoint_num, NULL,
3113                                     CVMX_USB_CALLBACK_TRANSFER_COMPLETE,
3114                                     CVMX_USB_COMPLETE_SUCCESS);
3115     }
3116
3117     usbc_doepint.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_DOEPINTX(endpoint_num, usb->index));
3118     __cvmx_usb_write_csr32(usb, CVMX_USBCX_DOEPINTX(endpoint_num, usb->index), usbc_doepint.u32);
3119     //cvmx_csr_db_decode(cvmx_get_proc_id(), CVMX_USBCX_DOEPINTX(endpoint_num, usb->index), usbc_doepint.u32);
3120     if (usbc_doepint.s.outtknepdis)
3121     {
3122         /* OUT Token Received When Endpoint Disabled (OUTTknEPdis)
3123             Applies only to control OUT endpoints.
3124             Indicates that an OUT token was received when the endpoint
3125             was not yet enabled. This interrupt is asserted on the endpoint
3126             for which the OUT token was received. */
3127         if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO))
3128             cvmx_dprintf("%s: Received OUT token on disabled endpoint %d\n", __FUNCTION__, endpoint_num);
3129     }
3130     if (usbc_doepint.s.setup)
3131     {
3132         /* SETUP Phase Done (SetUp)
3133             Applies to control OUT endpoints only.
3134             Indicates that the SETUP phase for the control endpoint is
3135             complete and no more back-to-back SETUP packets were
3136             received for the current control transfer. On this interrupt, the
3137             application can decode the received SETUP data packet. */
3138         __cvmx_usb_perform_callback(usb, usb->pipe + endpoint_num, NULL,
3139                                     CVMX_USB_CALLBACK_DEVICE_SETUP,
3140                                     CVMX_USB_COMPLETE_SUCCESS);
3141     }
3142     if (usbc_doepint.s.ahberr)
3143     {
3144         /* AHB Error (AHBErr)
3145             This is generated only in Internal DMA mode when there is an
3146             AHB error during an AHB read/write. The application can read
3147             the corresponding endpoint DMA address register to get the
3148             error address. */
3149         if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO))
3150             cvmx_dprintf("%s: AHB error on endpoint %d\n", __FUNCTION__, endpoint_num);
3151     }
3152     if (usbc_doepint.s.epdisbld)
3153     {
3154         /* Endpoint Disabled Interrupt (EPDisbld)
3155             This bit indicates that the endpoint is disabled per the
3156             application's request. */
3157         /* Nothing to do */
3158     }
3159     if (usbc_doepint.s.xfercompl)
3160     {
3161         /* Transfer Completed Interrupt (XferCompl)
3162             Indicates that the programmed transfer is complete on the AHB
3163             as well as on the USB, for this endpoint. */
3164         __cvmx_usb_perform_callback(usb, usb->pipe + endpoint_num, NULL,
3165                                     CVMX_USB_CALLBACK_TRANSFER_COMPLETE,
3166                                     CVMX_USB_COMPLETE_SUCCESS);
3167     }
3168
3169     CVMX_USB_RETURN(0);
3170 }
3171
3172
3173 /**
3174  * Poll the device mode endpoints for status
3175  *
3176  * @param usb  USB device state populated by
3177  *               cvmx_usb_initialize().
3178  *
3179  * @return Zero on success
3180  */
3181 static int __cvmx_usb_poll_endpoints(cvmx_usb_internal_state_t *usb)
3182 {
3183     cvmx_usbcx_daint_t usbc_daint;
3184     int active_endpoints;
3185
3186     CVMX_USB_LOG_CALLED();
3187     CVMX_USB_LOG_PARAM("%p", usb);
3188
3189     usbc_daint.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_DAINT(usb->index));
3190     active_endpoints = usbc_daint.s.inepint | usbc_daint.s.outepint;
3191
3192     while (active_endpoints)
3193     {
3194         int endpoint;
3195         CVMX_CLZ(endpoint, active_endpoints);
3196         endpoint = 31 - endpoint;
3197         __cvmx_usb_poll_endpoint(usb, endpoint);
3198         active_endpoints ^= 1<<endpoint;
3199     }
3200
3201     CVMX_USB_RETURN(0);
3202 }
3203
3204
3205 /**
3206  * Poll the USB block for status and call all needed callback
3207  * handlers. This function is meant to be called in the interrupt
3208  * handler for the USB controller. It can also be called
3209  * periodically in a loop for non-interrupt based operation.
3210  *
3211  * @param state  USB device state populated by
3212  *               cvmx_usb_initialize().
3213  *
3214  * @return CVMX_USB_SUCCESS or a negative error code defined in
3215  *         cvmx_usb_status_t.
3216  */
3217 cvmx_usb_status_t cvmx_usb_poll(cvmx_usb_state_t *state)
3218 {
3219     cvmx_usbcx_gintsts_t usbc_gintsts;
3220     cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
3221
3222     CVMX_PREFETCH(usb, 0);
3223     CVMX_PREFETCH(usb, 1*128);
3224     CVMX_PREFETCH(usb, 2*128);
3225     CVMX_PREFETCH(usb, 3*128);
3226     CVMX_PREFETCH(usb, 4*128);
3227
3228     CVMX_USB_LOG_CALLED();
3229     CVMX_USB_LOG_PARAM("%p", state);
3230
3231     /* Read the pending interrupts */
3232     usbc_gintsts.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GINTSTS(usb->index));
3233
3234     if (usbc_gintsts.s.wkupint)
3235     {
3236         /* Resume/Remote Wakeup Detected Interrupt (WkUpInt)
3237             In Device mode, this interrupt is asserted when a resume is
3238             detected on the USB. In Host mode, this interrupt is asserted
3239             when a remote wakeup is detected on the USB. */
3240         /* Octeon doesn't support suspend / resume */
3241     }
3242     if (usbc_gintsts.s.sessreqint)
3243     {
3244         /* Session Request/New Session Detected Interrupt (SessReqInt)
3245             In Host mode, this interrupt is asserted when a session request
3246             is detected from the device. In Device mode, this interrupt is
3247             asserted when the utmiotg_bvalid signal goes high. */
3248         /* Octeon doesn't support OTG */
3249     }
3250     if (usbc_gintsts.s.disconnint || usbc_gintsts.s.prtint)
3251     {
3252         cvmx_usbcx_hprt_t usbc_hprt;
3253         /* Disconnect Detected Interrupt (DisconnInt)
3254             Asserted when a device disconnect is detected. */
3255
3256         /* Host Port Interrupt (PrtInt)
3257             The core sets this bit to indicate a change in port status of one
3258             of the O2P USB core ports in Host mode. The application must
3259             read the Host Port Control and Status (HPRT) register to
3260             determine the exact event that caused this interrupt. The
3261             application must clear the appropriate status bit in the Host Port
3262             Control and Status register to clear this bit. */
3263
3264         /* Call the user's port callback */
3265         __cvmx_usb_perform_callback(usb, NULL, NULL,
3266                                     CVMX_USB_CALLBACK_PORT_CHANGED,
3267                                     CVMX_USB_COMPLETE_SUCCESS);
3268         /* Clear the port change bits */
3269         usbc_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
3270         usbc_hprt.s.prtena = 0;
3271         __cvmx_usb_write_csr32(usb, CVMX_USBCX_HPRT(usb->index), usbc_hprt.u32);
3272     }
3273     if (usbc_gintsts.s.conidstschng)
3274     {
3275         /* Connector ID Status Change (ConIDStsChng)
3276             The core sets this bit when there is a change in connector ID
3277             status. */
3278         /* The USB core currently doesn't support dynamically changing from
3279             host to device mode */
3280     }
3281     if (usbc_gintsts.s.ptxfemp)
3282     {
3283         /* Periodic TxFIFO Empty (PTxFEmp)
3284             Asserted when the Periodic Transmit FIFO is either half or
3285             completely empty and there is space for at least one entry to be
3286             written in the Periodic Request Queue. The half or completely
3287             empty status is determined by the Periodic TxFIFO Empty Level
3288             bit in the Core AHB Configuration register
3289             (GAHBCFG.PTxFEmpLvl). */
3290         /* In DMA mode we don't care */
3291     }
3292     if (usbc_gintsts.s.hchint)
3293     {
3294         /* Host Channels Interrupt (HChInt)
3295             The core sets this bit to indicate that an interrupt is pending on
3296             one of the channels of the core (in Host mode). The application
3297             must read the Host All Channels Interrupt (HAINT) register to
3298             determine the exact number of the channel on which the
3299             interrupt occurred, and then read the corresponding Host
3300             Channel-n Interrupt (HCINTn) register to determine the exact
3301             cause of the interrupt. The application must clear the
3302             appropriate status bit in the HCINTn register to clear this bit. */
3303         cvmx_usbcx_haint_t usbc_haint;
3304         usbc_haint.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HAINT(usb->index));
3305         while (usbc_haint.u32)
3306         {
3307             int channel;
3308             CVMX_CLZ(channel, usbc_haint.u32);
3309             channel = 31 - channel;
3310             __cvmx_usb_poll_channel(usb, channel);
3311             usbc_haint.u32 ^= 1<<channel;
3312         }
3313     }
3314     if (usbc_gintsts.s.fetsusp)
3315     {
3316         /* Data Fetch Suspended (FetSusp)
3317             This interrupt is valid only in DMA mode. This interrupt indicates
3318             that the core has stopped fetching data for IN endpoints due to
3319             the unavailability of TxFIFO space or Request Queue space.
3320             This interrupt is used by the application for an endpoint
3321             mismatch algorithm. */
3322         // FIXME
3323     }
3324     if (usbc_gintsts.s.incomplp)
3325     {
3326         /* Incomplete Periodic Transfer (incomplP)
3327             In Host mode, the core sets this interrupt bit when there are
3328             incomplete periodic transactions still pending which are
3329             scheduled for the current microframe.
3330             Incomplete Isochronous OUT Transfer (incompISOOUT)
3331             The Device mode, the core sets this interrupt to indicate that
3332             there is at least one isochronous OUT endpoint on which the
3333             transfer is not completed in the current microframe. This
3334             interrupt is asserted along with the End of Periodic Frame
3335             Interrupt (EOPF) bit in this register. */
3336         // FIXME
3337     }
3338     if (usbc_gintsts.s.incompisoin)
3339     {
3340         /* Incomplete Isochronous IN Transfer (incompISOIN)
3341             The core sets this interrupt to indicate that there is at least one
3342             isochronous IN endpoint on which the transfer is not completed
3343             in the current microframe. This interrupt is asserted along with
3344             the End of Periodic Frame Interrupt (EOPF) bit in this register. */
3345         // FIXME
3346     }
3347     if (usbc_gintsts.s.oepint)
3348     {
3349         /* OUT Endpoints Interrupt (OEPInt)
3350             The core sets this bit to indicate that an interrupt is pending on
3351             one of the OUT endpoints of the core (in Device mode). The
3352             application must read the Device All Endpoints Interrupt
3353             (DAINT) register to determine the exact number of the OUT
3354             endpoint on which the interrupt occurred, and then read the
3355             corresponding Device OUT Endpoint-n Interrupt (DOEPINTn)
3356             register to determine the exact cause of the interrupt. The
3357             application must clear the appropriate status bit in the
3358             corresponding DOEPINTn register to clear this bit. */
3359         __cvmx_usb_poll_endpoints(usb);
3360     }
3361     if (usbc_gintsts.s.iepint)
3362     {
3363         /* IN Endpoints Interrupt (IEPInt)
3364             The core sets this bit to indicate that an interrupt is pending on
3365             one of the IN endpoints of the core (in Device mode). The
3366             application must read the Device All Endpoints Interrupt
3367             (DAINT) register to determine the exact number of the IN
3368             endpoint on which the interrupt occurred, and then read the
3369             corresponding Device IN Endpoint-n Interrupt (DIEPINTn)
3370             register to determine the exact cause of the interrupt. The
3371             application must clear the appropriate status bit in the
3372             corresponding DIEPINTn register to clear this bit. */
3373         __cvmx_usb_poll_endpoints(usb);
3374     }
3375     if (usbc_gintsts.s.epmis)
3376     {
3377         /* Endpoint Mismatch Interrupt (EPMis)
3378             Indicates that an IN token has been received for a non-periodic
3379             endpoint, but the data for another endpoint is present in the top
3380             of the Non-Periodic Transmit FIFO and the IN endpoint
3381             mismatch count programmed by the application has expired. */
3382         // FIXME
3383     }
3384     if (usbc_gintsts.s.eopf)
3385     {
3386         /* End of Periodic Frame Interrupt (EOPF)
3387             Indicates that the period specified in the Periodic Frame Interval
3388             field of the Device Configuration register (DCFG.PerFrInt) has
3389             been reached in the current microframe. */
3390         // FIXME
3391     }
3392     if (usbc_gintsts.s.isooutdrop)
3393     {
3394         /* Isochronous OUT Packet Dropped Interrupt (ISOOutDrop)
3395             The core sets this bit when it fails to write an isochronous OUT
3396             packet into the RxFIFO because the RxFIFO doesn't have
3397             enough space to accommodate a maximum packet size packet
3398             for the isochronous OUT endpoint. */
3399         // FIXME
3400     }
3401     if (usbc_gintsts.s.enumdone)
3402     {
3403         /* Enumeration Done (EnumDone)
3404             The core sets this bit to indicate that speed enumeration is
3405             complete. The application must read the Device Status (DSTS)
3406             register to obtain the enumerated speed. */
3407         if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEVICE_MODE)
3408         {
3409             cvmx_usbcx_dsts_t usbc_dsts;
3410             usbc_dsts.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_DSTS(usb->index));
3411             if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO))
3412                 cvmx_dprintf("%s: USB%d Enumeration complete with %s speed\n",
3413                              __FUNCTION__, usb->index,
3414                              (usbc_dsts.s.enumspd == CVMX_USB_SPEED_HIGH) ? "high" :
3415                              (usbc_dsts.s.enumspd == CVMX_USB_SPEED_FULL) ? "full" :
3416                              "low");
3417             USB_SET_FIELD32(CVMX_USBCX_DIEPCTLX(0, usb->index),
3418                             cvmx_usbcx_diepctlx_t, mps,
3419                             (usbc_dsts.s.enumspd == CVMX_USB_SPEED_LOW) ? 3 : 0);
3420             USB_SET_FIELD32(CVMX_USBCX_DOEPCTLX(0, usb->index),
3421                             cvmx_usbcx_doepctlx_t, epena, 1);
3422         }
3423     }
3424     if (usbc_gintsts.s.usbrst)
3425     {
3426         /* USB Reset (USBRst)
3427             The core sets this bit to indicate that a reset is
3428             detected on the USB. */
3429         if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEVICE_MODE)
3430         {
3431             if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO))
3432                 cvmx_dprintf("%s: USB%d Reset complete\n", __FUNCTION__, usb->index);
3433             __cvmx_usb_device_reset_complete(usb);
3434         }
3435     }
3436     if (usbc_gintsts.s.nptxfemp)
3437     {
3438         /* Non-Periodic TxFIFO Empty (NPTxFEmp)
3439             This interrupt is asserted when the Non-Periodic TxFIFO is
3440             either half or completely empty, and there is space for at least
3441             one entry to be written to the Non-Periodic Transmit Request
3442             Queue. The half or completely empty status is determined by
3443             the Non-Periodic TxFIFO Empty Level bit in the Core AHB
3444             Configuration register (GAHBCFG.NPTxFEmpLvl). */
3445         /* In DMA mode this is handled by hardware */
3446     }
3447     if (usbc_gintsts.s.rxflvl)
3448     {
3449         /* RxFIFO Non-Empty (RxFLvl)
3450             Indicates that there is at least one packet pending to be read
3451             from the RxFIFO. */
3452         /* In DMA mode this is handled by hardware */
3453     }
3454     if (usbc_gintsts.s.sof)
3455     {
3456         /* Start of (micro)Frame (Sof)
3457             In Host mode, the core sets this bit to indicate that an SOF
3458             (FS), micro-SOF (HS), or Keep-Alive (LS) is transmitted on the
3459             USB. The application must write a 1 to this bit to clear the
3460             interrupt.
3461             In Device mode, in the core sets this bit to indicate that an SOF
3462             token has been received on the USB. The application can read
3463             the Device Status register to get the current (micro)frame
3464             number. This interrupt is seen only when the core is operating
3465             at either HS or FS. */
3466     }
3467     if (usbc_gintsts.s.otgint)
3468     {
3469         /* OTG Interrupt (OTGInt)
3470             The core sets this bit to indicate an OTG protocol event. The
3471             application must read the OTG Interrupt Status (GOTGINT)
3472             register to determine the exact event that caused this interrupt.
3473             The application must clear the appropriate status bit in the
3474             GOTGINT register to clear this bit. */
3475         /* Octeon doesn't support OTG, so ignore */
3476     }
3477     if (usbc_gintsts.s.modemis)
3478     {
3479         /* Mode Mismatch Interrupt (ModeMis)
3480             The core sets this bit when the application is trying to access:
3481             * A Host mode register, when the core is operating in Device
3482             mode
3483             * A Device mode register, when the core is operating in Host
3484             mode
3485             The register access is completed on the AHB with an OKAY
3486             response, but is ignored by the core internally and doesn't
3487             affect the operation of the core. */
3488         /* Ignored for now */
3489     }
3490
3491     __cvmx_usb_schedule(usb, usbc_gintsts.s.sof);
3492
3493     /* Clear the interrupts now that we know about them */
3494     __cvmx_usb_write_csr32(usb, CVMX_USBCX_GINTSTS(usb->index), usbc_gintsts.u32);
3495
3496     CVMX_USB_RETURN(CVMX_USB_SUCCESS);
3497 }
3498
3499
3500 /**
3501  * Enable an endpoint for use in device mode. After this call
3502  * transactions will be allowed over the endpoint. This must be
3503  * called after every usb reset.
3504  *
3505  * @param state  USB device state populated by
3506  *               cvmx_usb_initialize().
3507  * @param endpoint_num
3508  *               The endpoint number to enable (0-4)
3509  * @param transfer_type
3510  *               USB transfer type of this endpoint
3511  * @param transfer_dir
3512  *               Direction of transfer relative to Octeon
3513  * @param max_packet_size
3514  *               Maximum packet size support by this endpoint
3515  * @param buffer Buffer to send/receive
3516  * @param buffer_length
3517  *               Length of the buffer in bytes
3518  *
3519  * @return CVMX_USB_SUCCESS or a negative error code defined in
3520  *         cvmx_usb_status_t.
3521  */
3522 cvmx_usb_status_t cvmx_usb_device_enable_endpoint(cvmx_usb_state_t *state,
3523                                                   int endpoint_num,
3524                                                   cvmx_usb_transfer_t transfer_type,
3525                                                   cvmx_usb_direction_t transfer_dir,
3526                                                   int max_packet_size,
3527                                                   uint64_t buffer,
3528                                                   int buffer_length)
3529 {
3530     cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
3531
3532     CVMX_USB_LOG_CALLED();
3533     CVMX_USB_LOG_PARAM("%p", state);
3534     CVMX_USB_LOG_PARAM("%d", endpoint_num);
3535     CVMX_USB_LOG_PARAM("%d", transfer_type);
3536     CVMX_USB_LOG_PARAM("%d", transfer_dir);
3537     CVMX_USB_LOG_PARAM("%d", max_packet_size);
3538     CVMX_USB_LOG_PARAM("0x%llx", (unsigned long long)buffer);
3539     CVMX_USB_LOG_PARAM("%d", buffer_length);
3540
3541     if (cvmx_unlikely((endpoint_num < 0) || (endpoint_num > 4)))
3542         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
3543     if (cvmx_unlikely(transfer_type > CVMX_USB_TRANSFER_INTERRUPT))
3544         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
3545     if (cvmx_unlikely((transfer_dir != CVMX_USB_DIRECTION_OUT) &&
3546         (transfer_dir != CVMX_USB_DIRECTION_IN)))
3547         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
3548     if (cvmx_unlikely((max_packet_size < 0) || (max_packet_size > 512)))
3549         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
3550     if (cvmx_unlikely(!buffer))
3551         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
3552     if (cvmx_unlikely(buffer_length < 0))
3553         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
3554     if (cvmx_unlikely((usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEVICE_MODE) == 0))
3555         CVMX_USB_RETURN(CVMX_USB_INCORRECT_MODE);
3556
3557     if (transfer_dir == CVMX_USB_DIRECTION_IN)
3558     {
3559         cvmx_usbcx_doepctlx_t usbc_doepctl;
3560         cvmx_usbcx_doeptsizx_t usbc_doeptsiz;
3561
3562         /* Setup the locations the DMA engines use  */
3563         __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_INB_CHN0(usb->index) + endpoint_num*8, buffer);
3564         usbc_doeptsiz.u32 = 0;
3565         usbc_doeptsiz.s.mc = 1; // FIXME
3566         usbc_doeptsiz.s.pktcnt = (buffer_length + max_packet_size - 1) / max_packet_size;
3567         if (usbc_doeptsiz.s.pktcnt == 0)
3568             usbc_doeptsiz.s.pktcnt = 1;
3569         usbc_doeptsiz.s.xfersize = buffer_length;
3570         __cvmx_usb_write_csr32(usb, CVMX_USBCX_DOEPTSIZX(endpoint_num, usb->index), usbc_doeptsiz.u32);
3571
3572         usbc_doepctl.u32 = 0;
3573         usbc_doepctl.s.epena = 1;
3574         usbc_doepctl.s.setd1pid = 0; // FIXME
3575         usbc_doepctl.s.setd0pid = 0; // FIXME
3576         usbc_doepctl.s.cnak = 1;
3577         usbc_doepctl.s.eptype = transfer_type;
3578         usbc_doepctl.s.usbactep = 1;
3579         usbc_doepctl.s.mps = max_packet_size;
3580         __cvmx_usb_write_csr32(usb, CVMX_USBCX_DOEPCTLX(endpoint_num, usb->index), usbc_doepctl.u32);
3581     }
3582     else
3583     {
3584         cvmx_usbcx_diepctlx_t usbc_diepctl;
3585         cvmx_usbcx_dieptsizx_t usbc_dieptsiz;
3586
3587         /* Setup the locations the DMA engines use  */
3588         __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + endpoint_num*8, buffer);
3589         usbc_dieptsiz.u32 = 0;
3590         usbc_dieptsiz.s.mc = 1; // FIXME
3591         usbc_dieptsiz.s.pktcnt = (buffer_length + max_packet_size - 1) / max_packet_size;
3592         if (usbc_dieptsiz.s.pktcnt == 0)
3593             usbc_dieptsiz.s.pktcnt = 1;
3594         usbc_dieptsiz.s.xfersize = buffer_length;
3595         __cvmx_usb_write_csr32(usb, CVMX_USBCX_DIEPTSIZX(endpoint_num, usb->index), usbc_dieptsiz.u32);
3596
3597         usbc_diepctl.u32 = 0;
3598         usbc_diepctl.s.epena = 1;
3599         usbc_diepctl.s.setd1pid = 0; // FIXME
3600         usbc_diepctl.s.setd0pid = 0; // FIXME
3601         usbc_diepctl.s.cnak = 1;
3602         if ((transfer_type == CVMX_USB_TRANSFER_INTERRUPT) ||
3603             (transfer_type == CVMX_USB_TRANSFER_ISOCHRONOUS))
3604             usbc_diepctl.s.txfnum = endpoint_num; // FIXME
3605         else
3606             usbc_diepctl.s.txfnum = 0;
3607         usbc_diepctl.s.eptype = transfer_type;
3608         usbc_diepctl.s.usbactep = 1;
3609         usbc_diepctl.s.nextep = endpoint_num - 1; // FIXME
3610         usbc_diepctl.s.mps = max_packet_size;
3611         __cvmx_usb_write_csr32(usb, CVMX_USBCX_DIEPCTLX(endpoint_num, usb->index), usbc_diepctl.u32);
3612     }
3613
3614     CVMX_USB_RETURN(CVMX_USB_SUCCESS);
3615 }
3616
3617
3618 /**
3619  * Disable an endpoint in device mode.
3620  *
3621  * @param state  USB device state populated by
3622  *               cvmx_usb_initialize().
3623  * @param endpoint_num
3624  *               The endpoint number to disable (0-4)
3625  *
3626  * @return CVMX_USB_SUCCESS or a negative error code defined in
3627  *         cvmx_usb_status_t.
3628  */
3629 cvmx_usb_status_t cvmx_usb_device_disable_endpoint(cvmx_usb_state_t *state,
3630                                                    int endpoint_num)
3631 {
3632     cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
3633
3634     CVMX_USB_LOG_CALLED();
3635     CVMX_USB_LOG_PARAM("%p", state);
3636     CVMX_USB_LOG_PARAM("%d", endpoint_num);
3637
3638     if (cvmx_unlikely((endpoint_num < 0) || (endpoint_num > 4)))
3639         CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
3640     if (cvmx_unlikely((usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEVICE_MODE) == 0))
3641         CVMX_USB_RETURN(CVMX_USB_INCORRECT_MODE);
3642
3643     USB_SET_FIELD32(CVMX_USBCX_DOEPCTLX(endpoint_num, usb->index),
3644                     cvmx_usbcx_doepctlx_t, epdis, 1);
3645     USB_SET_FIELD32(CVMX_USBCX_DIEPCTLX(endpoint_num, usb->index),
3646                     cvmx_usbcx_diepctlx_t, epdis, 1);
3647
3648     CVMX_USB_RETURN(CVMX_USB_SUCCESS);
3649 }
3650
3651 extern void cvmx_usb_set_toggle(cvmx_usb_state_t *state, int endpoint_num, int toggle)
3652 {
3653     cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
3654     cvmx_usb_pipe_t *pipe = usb->pipe + endpoint_num;
3655
3656     pipe->pid_toggle = !!toggle;
3657 }
3658
3659 extern int cvmx_usb_get_toggle(cvmx_usb_state_t *state, int endpoint_num)
3660 {
3661     cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
3662     cvmx_usb_pipe_t *pipe = usb->pipe + endpoint_num;
3663
3664     if (pipe->pid_toggle)
3665             return (1);
3666     return (0);
3667 }