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