1 /***********************license start***************
2 * Copyright (c) 2003-2010 Cavium Inc. (support@cavium.com). All rights
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
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
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
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**************************************/
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
50 * <hr>$Revision: 32636 $<hr>
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>
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
66 #include <asm/octeon/cvmx-error.h>
70 #include "cvmx-clock.h"
71 #include "cvmx-sysinfo.h"
73 #include "cvmx-helper.h"
74 #include "cvmx-helper-board.h"
75 #if !defined(CVMX_BUILD_FOR_FREEBSD_KERNEL)
76 #include "cvmx-csr-db.h"
78 #include "cvmx-swap.h"
79 #if !defined(CVMX_BUILD_FOR_FREEBSD_KERNEL)
80 #include "cvmx-error.h"
84 #define MAX_RETRIES 3 /* Maximum number of times to retry failed transactions */
85 #define MAX_PIPES 32 /* Maximum number of pipes that can be open at once */
86 #define MAX_TRANSACTIONS 256 /* Maximum number of outstanding transactions across all pipes */
87 #define MAX_CHANNELS 8 /* Maximum number of hardware channels supported by the USB block */
88 #define MAX_USB_ADDRESS 127 /* The highest valid USB device address */
89 #define MAX_USB_ENDPOINT 15 /* The highest valid USB endpoint number */
90 #define MAX_USB_HUB_PORT 15 /* The highest valid port number on a hub */
91 #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 */
92 #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 */
93 #define ALLOW_CSR_DECODES 0 /* CSR decoding when CVMX_USB_INITIALIZE_FLAGS_DEBUG_CSRS is set
94 enlarges the code a lot. This define overrides the ability to do CSR
95 decoding since it isn't necessary 99% of the time. Change this to a
96 one if you need CSR decoding */
98 /* These defines disable the normal read and write csr. This is so I can add
99 extra debug stuff to the usb specific version and I won't use the normal
100 version by mistake */
101 #define cvmx_read_csr use_cvmx_usb_read_csr64_instead_of_cvmx_read_csr
102 #define cvmx_write_csr use_cvmx_usb_write_csr64_instead_of_cvmx_write_csr
106 __CVMX_USB_TRANSACTION_FLAGS_IN_USE = 1<<16,
107 } cvmx_usb_transaction_flags_t;
110 * Logical transactions may take numerous low level
111 * transactions, especially when splits are concerned. This
112 * enum represents all of the possible stages a transaction can
113 * be in. Note that split completes are always even. This is so
114 * the NAK handler can backup to the previous low level
115 * transaction with a simple clearing of bit 0.
119 CVMX_USB_STAGE_NON_CONTROL,
120 CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE,
121 CVMX_USB_STAGE_SETUP,
122 CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE,
124 CVMX_USB_STAGE_DATA_SPLIT_COMPLETE,
125 CVMX_USB_STAGE_STATUS,
126 CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE,
130 * This structure describes each pending USB transaction
131 * regardless of type. These are linked together to form a list
132 * of pending requests for a pipe.
134 typedef struct cvmx_usb_transaction
136 struct cvmx_usb_transaction *prev; /**< Transaction before this one in the pipe */
137 struct cvmx_usb_transaction *next; /**< Transaction after this one in the pipe */
138 cvmx_usb_transfer_t type; /**< Type of transaction, duplicated of the pipe */
139 cvmx_usb_transaction_flags_t flags; /**< State flags for this transaction */
140 uint64_t buffer; /**< User's physical buffer address to read/write */
141 int buffer_length; /**< Size of the user's buffer in bytes */
142 uint64_t control_header; /**< For control transactions, physical address of the 8 byte standard header */
143 int iso_start_frame; /**< For ISO transactions, the starting frame number */
144 int iso_number_packets; /**< For ISO transactions, the number of packets in the request */
145 cvmx_usb_iso_packet_t *iso_packets; /**< For ISO transactions, the sub packets in the request */
149 int actual_bytes; /**< Actual bytes transfer for this transaction */
150 cvmx_usb_stage_t stage; /**< For control transactions, the current stage */
151 cvmx_usb_callback_func_t callback; /**< User's callback function when complete */
152 void *callback_data; /**< User's data */
153 } cvmx_usb_transaction_t;
156 * A pipe represents a virtual connection between Octeon and some
157 * USB device. It contains a list of pending request to the device.
159 typedef struct cvmx_usb_pipe
161 struct cvmx_usb_pipe *prev; /**< Pipe before this one in the list */
162 struct cvmx_usb_pipe *next; /**< Pipe after this one in the list */
163 cvmx_usb_transaction_t *head; /**< The first pending transaction */
164 cvmx_usb_transaction_t *tail; /**< The last pending transaction */
165 uint64_t interval; /**< For periodic pipes, the interval between packets in frames */
166 uint64_t next_tx_frame; /**< The next frame this pipe is allowed to transmit on */
167 cvmx_usb_pipe_flags_t flags; /**< State flags for this pipe */
168 cvmx_usb_speed_t device_speed; /**< Speed of device connected to this pipe */
169 cvmx_usb_transfer_t transfer_type; /**< Type of transaction supported by this pipe */
170 cvmx_usb_direction_t transfer_dir; /**< IN or OUT. Ignored for Control */
171 int multi_count; /**< Max packet in a row for the device */
172 uint16_t max_packet; /**< The device's maximum packet size in bytes */
173 uint8_t device_addr; /**< USB device address at other end of pipe */
174 uint8_t endpoint_num; /**< USB endpoint number at other end of pipe */
175 uint8_t hub_device_addr; /**< Hub address this device is connected to */
176 uint8_t hub_port; /**< Hub port this device is connected to */
177 uint8_t pid_toggle; /**< This toggles between 0/1 on every packet send to track the data pid needed */
178 uint8_t channel; /**< Hardware DMA channel for this pipe */
179 int8_t split_sc_frame; /**< The low order bits of the frame number the split complete should be sent on */
184 cvmx_usb_pipe_t *head; /**< Head of the list, or NULL if empty */
185 cvmx_usb_pipe_t *tail; /**< Tail if the list, or NULL if empty */
186 } cvmx_usb_pipe_list_t;
195 } entry[MAX_CHANNELS+1];
198 } cvmx_usb_tx_fifo_t;
201 * The state of the USB block is stored in this structure
205 int init_flags; /**< Flags passed to initialize */
206 int index; /**< Which USB block this is for */
207 int idle_hardware_channels; /**< Bit set for every idle hardware channel */
208 cvmx_usbcx_hprt_t usbcx_hprt; /**< Stored port status so we don't need to read a CSR to determine splits */
209 cvmx_usb_pipe_t *pipe_for_channel[MAX_CHANNELS]; /**< Map channels to pipes */
210 cvmx_usb_transaction_t *free_transaction_head; /**< List of free transactions head */
211 cvmx_usb_transaction_t *free_transaction_tail; /**< List of free transactions tail */
212 cvmx_usb_pipe_t pipe[MAX_PIPES]; /**< Storage for pipes */
213 cvmx_usb_transaction_t transaction[MAX_TRANSACTIONS]; /**< Storage for transactions */
214 cvmx_usb_callback_func_t callback[__CVMX_USB_CALLBACK_END]; /**< User global callbacks */
215 void *callback_data[__CVMX_USB_CALLBACK_END]; /**< User data for each callback */
216 int indent; /**< Used by debug output to indent functions */
217 cvmx_usb_port_status_t port_status; /**< Last port status used for change notification */
218 cvmx_usb_pipe_list_t free_pipes; /**< List of all pipes that are currently closed */
219 cvmx_usb_pipe_list_t idle_pipes; /**< List of open pipes that have no transactions */
220 cvmx_usb_pipe_list_t active_pipes[4]; /**< Active pipes indexed by transfer type */
221 uint64_t frame_number; /**< Increments every SOF interrupt for time keeping */
222 cvmx_usb_transaction_t *active_split; /**< Points to the current active split, or NULL */
223 cvmx_usb_tx_fifo_t periodic;
224 cvmx_usb_tx_fifo_t nonperiodic;
225 } cvmx_usb_internal_state_t;
227 /* This macro logs out whenever a function is called if debugging is on */
228 #define CVMX_USB_LOG_CALLED() \
229 if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CALLS)) \
230 cvmx_dprintf("%*s%s: called\n", 2*usb->indent++, "", __FUNCTION__);
232 /* This macro logs out each function parameter if debugging is on */
233 #define CVMX_USB_LOG_PARAM(format, param) \
234 if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CALLS)) \
235 cvmx_dprintf("%*s%s: param %s = " format "\n", 2*usb->indent, "", __FUNCTION__, #param, param);
237 /* This macro logs out when a function returns a value */
238 #define CVMX_USB_RETURN(v) \
241 if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CALLS)) \
242 cvmx_dprintf("%*s%s: returned %s(%d)\n", 2*--usb->indent, "", __FUNCTION__, #v, r); \
246 /* This macro logs out when a function doesn't return a value */
247 #define CVMX_USB_RETURN_NOTHING() \
249 if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CALLS)) \
250 cvmx_dprintf("%*s%s: returned\n", 2*--usb->indent, "", __FUNCTION__); \
254 /* This macro spins on a field waiting for it to reach a value */
255 #define CVMX_WAIT_FOR_FIELD32(address, type, field, op, value, timeout_usec)\
258 uint64_t done = cvmx_get_cycle() + (uint64_t)timeout_usec * \
259 cvmx_clock_get_rate(CVMX_CLOCK_CORE) / 1000000; \
263 c.u32 = __cvmx_usb_read_csr32(usb, address); \
264 if (c.s.field op (value)) { \
267 } else if (cvmx_get_cycle() > done) { \
276 /* This macro logically sets a single field in a CSR. It does the sequence
277 read, modify, and write */
278 #define USB_SET_FIELD32(address, type, field, value)\
281 c.u32 = __cvmx_usb_read_csr32(usb, address);\
283 __cvmx_usb_write_csr32(usb, address, c.u32);\
286 /* Returns the IO address to push/pop stuff data from the FIFOs */
287 #define USB_FIFO_ADDRESS(channel, usb_index) (CVMX_USBCX_GOTGCTL(usb_index) + ((channel)+1)*0x1000)
291 * Read a USB 32bit CSR. It performs the necessary address swizzle
292 * for 32bit CSRs and logs the value in a readable format if
295 * @param usb USB block this access is for
296 * @param address 64bit address to read
298 * @return Result of the read
300 static inline uint32_t __cvmx_usb_read_csr32(cvmx_usb_internal_state_t *usb,
303 uint32_t result = cvmx_read64_uint32(address ^ 4);
304 #if ALLOW_CSR_DECODES
305 if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CSRS))
307 cvmx_dprintf("Read: ");
308 cvmx_csr_db_decode(cvmx_get_proc_id(), address, result);
317 * Write a USB 32bit CSR. It performs the necessary address
318 * swizzle for 32bit CSRs and logs the value in a readable format
319 * if debugging is on.
321 * @param usb USB block this access is for
322 * @param address 64bit address to write
323 * @param value Value to write
325 static inline void __cvmx_usb_write_csr32(cvmx_usb_internal_state_t *usb,
326 uint64_t address, uint32_t value)
328 #if ALLOW_CSR_DECODES
329 if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CSRS))
331 cvmx_dprintf("Write: ");
332 cvmx_csr_db_decode(cvmx_get_proc_id(), address, value);
335 cvmx_write64_uint32(address ^ 4, value);
336 cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index));
342 * Read a USB 64bit CSR. It logs the value in a readable format if
345 * @param usb USB block this access is for
346 * @param address 64bit address to read
348 * @return Result of the read
350 static inline uint64_t __cvmx_usb_read_csr64(cvmx_usb_internal_state_t *usb,
353 uint64_t result = cvmx_read64_uint64(address);
354 #if ALLOW_CSR_DECODES
355 if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CSRS))
357 cvmx_dprintf("Read: ");
358 cvmx_csr_db_decode(cvmx_get_proc_id(), address, result);
367 * Write a USB 64bit CSR. It logs the value in a readable format
368 * if debugging is on.
370 * @param usb USB block this access is for
371 * @param address 64bit address to write
372 * @param value Value to write
374 static inline void __cvmx_usb_write_csr64(cvmx_usb_internal_state_t *usb,
375 uint64_t address, uint64_t value)
377 #if ALLOW_CSR_DECODES
378 if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CSRS))
380 cvmx_dprintf("Write: ");
381 cvmx_csr_db_decode(cvmx_get_proc_id(), address, value);
384 cvmx_write64_uint64(address, value);
390 * Utility function to convert complete codes into strings
392 * @param complete_code
395 * @return Human readable string
397 static const char *__cvmx_usb_complete_to_string(cvmx_usb_complete_t complete_code)
399 switch (complete_code)
401 case CVMX_USB_COMPLETE_SUCCESS: return "SUCCESS";
402 case CVMX_USB_COMPLETE_SHORT: return "SHORT";
403 case CVMX_USB_COMPLETE_CANCEL: return "CANCEL";
404 case CVMX_USB_COMPLETE_ERROR: return "ERROR";
405 case CVMX_USB_COMPLETE_STALL: return "STALL";
406 case CVMX_USB_COMPLETE_XACTERR: return "XACTERR";
407 case CVMX_USB_COMPLETE_DATATGLERR: return "DATATGLERR";
408 case CVMX_USB_COMPLETE_BABBLEERR: return "BABBLEERR";
409 case CVMX_USB_COMPLETE_FRAMEERR: return "FRAMEERR";
411 return "Update __cvmx_usb_complete_to_string";
417 * Return non zero if this pipe connects to a non HIGH speed
418 * device through a high speed hub.
420 * @param usb USB block this access is for
421 * @param pipe Pipe to check
423 * @return Non zero if we need to do split transactions
425 static inline int __cvmx_usb_pipe_needs_split(cvmx_usb_internal_state_t *usb, cvmx_usb_pipe_t *pipe)
427 return ((pipe->device_speed != CVMX_USB_SPEED_HIGH) && (usb->usbcx_hprt.s.prtspd == CVMX_USB_SPEED_HIGH));
433 * Trivial utility function to return the correct PID for a pipe
435 * @param pipe pipe to check
437 * @return PID for pipe
439 static inline int __cvmx_usb_get_data_pid(cvmx_usb_pipe_t *pipe)
441 if (pipe->pid_toggle)
442 return 2; /* Data1 */
444 return 0; /* Data0 */
449 * Return the number of USB ports supported by this Octeon
450 * chip. If the chip doesn't support USB, or is not supported
451 * by this API, a zero will be returned. Most Octeon chips
452 * support one usb port, but some support two ports.
453 * cvmx_usb_initialize() must be called on independent
454 * cvmx_usb_state_t structures.
456 * This utilizes cvmx_helper_board_usb_get_num_ports()
457 * to get any board specific variations.
459 * @return Number of port, zero if usb isn't supported
461 int cvmx_usb_get_num_ports(void)
465 if (OCTEON_IS_MODEL(OCTEON_CN56XX))
467 else if (OCTEON_IS_MODEL(OCTEON_CN52XX))
469 else if (OCTEON_IS_MODEL(OCTEON_CN50XX))
471 else if (OCTEON_IS_MODEL(OCTEON_CN31XX))
473 else if (OCTEON_IS_MODEL(OCTEON_CN30XX))
478 return __cvmx_helper_board_usb_get_num_ports(arch_ports);
480 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
481 EXPORT_SYMBOL(cvmx_usb_get_num_ports);
487 * Allocate a usb transaction for use
489 * @param usb USB device state populated by
490 * cvmx_usb_initialize().
492 * @return Transaction or NULL
494 static inline cvmx_usb_transaction_t *__cvmx_usb_alloc_transaction(cvmx_usb_internal_state_t *usb)
496 cvmx_usb_transaction_t *t;
497 t = usb->free_transaction_head;
500 usb->free_transaction_head = t->next;
501 if (!usb->free_transaction_head)
502 usb->free_transaction_tail = NULL;
504 else if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO))
505 cvmx_dprintf("%s: Failed to allocate a transaction\n", __FUNCTION__);
508 memset(t, 0, sizeof(*t));
509 t->flags = __CVMX_USB_TRANSACTION_FLAGS_IN_USE;
517 * Free a usb transaction
519 * @param usb USB device state populated by
520 * cvmx_usb_initialize().
522 * Transaction to free
524 static inline void __cvmx_usb_free_transaction(cvmx_usb_internal_state_t *usb,
525 cvmx_usb_transaction_t *transaction)
527 transaction->flags = 0;
528 transaction->prev = NULL;
529 transaction->next = NULL;
530 if (usb->free_transaction_tail)
531 usb->free_transaction_tail->next = transaction;
533 usb->free_transaction_head = transaction;
534 usb->free_transaction_tail = transaction;
540 * Add a pipe to the tail of a list
541 * @param list List to add pipe to
542 * @param pipe Pipe to add
544 static inline void __cvmx_usb_append_pipe(cvmx_usb_pipe_list_t *list, cvmx_usb_pipe_t *pipe)
547 pipe->prev = list->tail;
549 list->tail->next = pipe;
558 * Remove a pipe from a list
559 * @param list List to remove pipe from
560 * @param pipe Pipe to remove
562 static inline void __cvmx_usb_remove_pipe(cvmx_usb_pipe_list_t *list, cvmx_usb_pipe_t *pipe)
564 if (list->head == pipe)
566 list->head = pipe->next;
569 list->head->prev = NULL;
573 else if (list->tail == pipe)
575 list->tail = pipe->prev;
576 list->tail->next = NULL;
581 pipe->prev->next = pipe->next;
582 pipe->next->prev = pipe->prev;
590 * Initialize a USB port for use. This must be called before any
591 * other access to the Octeon USB port is made. The port starts
592 * off in the disabled state.
594 * @param state Pointer to an empty cvmx_usb_state_t structure
595 * that will be populated by the initialize call.
596 * This structure is then passed to all other USB
598 * @param usb_port_number
599 * Which Octeon USB port to initialize.
600 * @param flags Flags to control hardware initialization. See
601 * cvmx_usb_initialize_flags_t for the flag
602 * definitions. Some flags are mandatory.
604 * @return CVMX_USB_SUCCESS or a negative error code defined in
607 cvmx_usb_status_t cvmx_usb_initialize(cvmx_usb_state_t *state,
609 cvmx_usb_initialize_flags_t flags)
611 cvmx_usbnx_clk_ctl_t usbn_clk_ctl;
612 cvmx_usbnx_usbp_ctl_status_t usbn_usbp_ctl_status;
613 cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
615 usb->init_flags = flags;
616 CVMX_USB_LOG_CALLED();
617 CVMX_USB_LOG_PARAM("%p", state);
618 CVMX_USB_LOG_PARAM("%d", usb_port_number);
619 CVMX_USB_LOG_PARAM("0x%x", flags);
621 /* Make sure that state is large enough to store the internal state */
622 if (sizeof(*state) < sizeof(*usb))
623 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
624 /* At first allow 0-1 for the usb port number */
625 if ((usb_port_number < 0) || (usb_port_number > 1))
626 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
627 /* For all chips except 52XX there is only one port */
628 if (!OCTEON_IS_MODEL(OCTEON_CN52XX) && (usb_port_number > 0))
629 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
630 /* Try to determine clock type automatically */
631 if ((flags & (CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI |
632 CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND)) == 0)
634 if (__cvmx_helper_board_usb_get_clock_type() == USB_CLOCK_TYPE_CRYSTAL_12)
635 flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI; /* Only 12 MHZ crystals are supported */
637 flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND;
640 if (flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND)
642 /* Check for auto ref clock frequency */
643 if (!(flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK))
644 switch (__cvmx_helper_board_usb_get_clock_type())
646 case USB_CLOCK_TYPE_REF_12:
647 flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ;
649 case USB_CLOCK_TYPE_REF_24:
650 flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ;
652 case USB_CLOCK_TYPE_REF_48:
653 flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ;
656 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
661 memset(usb, 0, sizeof(*usb));
662 usb->init_flags = flags;
664 /* Initialize the USB state structure */
667 usb->index = usb_port_number;
669 /* Initialize the transaction double linked list */
670 usb->free_transaction_head = NULL;
671 usb->free_transaction_tail = NULL;
672 for (i=0; i<MAX_TRANSACTIONS; i++)
673 __cvmx_usb_free_transaction(usb, usb->transaction + i);
674 for (i=0; i<MAX_PIPES; i++)
675 __cvmx_usb_append_pipe(&usb->free_pipes, usb->pipe + i);
678 /* Power On Reset and PHY Initialization */
680 /* 1. Wait for DCOK to assert (nothing to do) */
681 /* 2a. Write USBN0/1_CLK_CTL[POR] = 1 and
682 USBN0/1_CLK_CTL[HRST,PRST,HCLK_RST] = 0 */
683 usbn_clk_ctl.u64 = __cvmx_usb_read_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index));
684 usbn_clk_ctl.s.por = 1;
685 usbn_clk_ctl.s.hrst = 0;
686 usbn_clk_ctl.s.prst = 0;
687 usbn_clk_ctl.s.hclk_rst = 0;
688 usbn_clk_ctl.s.enable = 0;
689 /* 2b. Select the USB reference clock/crystal parameters by writing
690 appropriate values to USBN0/1_CLK_CTL[P_C_SEL, P_RTYPE, P_COM_ON] */
691 if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND)
693 /* The USB port uses 12/24/48MHz 2.5V board clock
694 source at USB_XO. USB_XI should be tied to GND.
695 Most Octeon evaluation boards require this setting */
696 if (OCTEON_IS_MODEL(OCTEON_CN3XXX))
698 usbn_clk_ctl.cn31xx.p_rclk = 1; /* From CN31XX,CN30XX manual */
699 usbn_clk_ctl.cn31xx.p_xenbn = 0;
701 else if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN50XX))
702 usbn_clk_ctl.cn56xx.p_rtype = 2; /* From CN56XX,CN50XX manual */
704 usbn_clk_ctl.cn52xx.p_rtype = 1; /* From CN52XX manual */
706 switch (flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK)
708 case CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ:
709 usbn_clk_ctl.s.p_c_sel = 0;
711 case CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ:
712 usbn_clk_ctl.s.p_c_sel = 1;
714 case CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ:
715 usbn_clk_ctl.s.p_c_sel = 2;
721 /* The USB port uses a 12MHz crystal as clock source
722 at USB_XO and USB_XI */
723 if (OCTEON_IS_MODEL(OCTEON_CN3XXX))
725 usbn_clk_ctl.cn31xx.p_rclk = 1; /* From CN31XX,CN30XX manual */
726 usbn_clk_ctl.cn31xx.p_xenbn = 1;
728 else if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN50XX))
729 usbn_clk_ctl.cn56xx.p_rtype = 0; /* From CN56XX,CN50XX manual */
731 usbn_clk_ctl.cn52xx.p_rtype = 0; /* From CN52XX manual */
733 usbn_clk_ctl.s.p_c_sel = 0;
735 /* 2c. Select the HCLK via writing USBN0/1_CLK_CTL[DIVIDE, DIVIDE2] and
736 setting USBN0/1_CLK_CTL[ENABLE] = 1. Divide the core clock down such
737 that USB is as close as possible to 125Mhz */
739 int divisor = (cvmx_clock_get_rate(CVMX_CLOCK_CORE)+125000000-1)/125000000;
740 if (divisor < 4) /* Lower than 4 doesn't seem to work properly */
742 usbn_clk_ctl.s.divide = divisor;
743 usbn_clk_ctl.s.divide2 = 0;
745 __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
747 /* 2d. Write USBN0/1_CLK_CTL[HCLK_RST] = 1 */
748 usbn_clk_ctl.s.hclk_rst = 1;
749 __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
751 /* 2e. Wait 64 core-clock cycles for HCLK to stabilize */
753 /* 3. Program the power-on reset field in the USBN clock-control register:
754 USBN_CLK_CTL[POR] = 0 */
755 usbn_clk_ctl.s.por = 0;
756 __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
758 /* 4. Wait 1 ms for PHY clock to start */
759 cvmx_wait_usec(1000);
760 /* 5. Program the Reset input from automatic test equipment field in the
761 USBP control and status register: USBN_USBP_CTL_STATUS[ATE_RESET] = 1 */
762 usbn_usbp_ctl_status.u64 = __cvmx_usb_read_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index));
763 usbn_usbp_ctl_status.s.ate_reset = 1;
764 __cvmx_usb_write_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index),
765 usbn_usbp_ctl_status.u64);
766 /* 6. Wait 10 cycles */
768 /* 7. Clear ATE_RESET field in the USBN clock-control register:
769 USBN_USBP_CTL_STATUS[ATE_RESET] = 0 */
770 usbn_usbp_ctl_status.s.ate_reset = 0;
771 __cvmx_usb_write_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index),
772 usbn_usbp_ctl_status.u64);
773 /* 8. Program the PHY reset field in the USBN clock-control register:
774 USBN_CLK_CTL[PRST] = 1 */
775 usbn_clk_ctl.s.prst = 1;
776 __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
778 /* 9. Program the USBP control and status register to select host or
779 device mode. USBN_USBP_CTL_STATUS[HST_MODE] = 0 for host, = 1 for
781 usbn_usbp_ctl_status.s.hst_mode = 0;
782 __cvmx_usb_write_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index),
783 usbn_usbp_ctl_status.u64);
786 /* 11. Program the hreset_n field in the USBN clock-control register:
787 USBN_CLK_CTL[HRST] = 1 */
788 usbn_clk_ctl.s.hrst = 1;
789 __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
791 /* 12. Proceed to USB core initialization */
792 usbn_clk_ctl.s.enable = 1;
793 __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
797 /* USB Core Initialization */
799 /* 1. Read USBC_GHWCFG1, USBC_GHWCFG2, USBC_GHWCFG3, USBC_GHWCFG4 to
800 determine USB core configuration parameters. */
802 /* 2. Program the following fields in the global AHB configuration
803 register (USBC_GAHBCFG)
804 DMA mode, USBC_GAHBCFG[DMAEn]: 1 = DMA mode, 0 = slave mode
805 Burst length, USBC_GAHBCFG[HBSTLEN] = 0
806 Nonperiodic TxFIFO empty level (slave mode only),
807 USBC_GAHBCFG[NPTXFEMPLVL]
808 Periodic TxFIFO empty level (slave mode only),
809 USBC_GAHBCFG[PTXFEMPLVL]
810 Global interrupt mask, USBC_GAHBCFG[GLBLINTRMSK] = 1 */
812 cvmx_usbcx_gahbcfg_t usbcx_gahbcfg;
813 /* Due to an errata, CN31XX doesn't support DMA */
814 if (OCTEON_IS_MODEL(OCTEON_CN31XX))
815 usb->init_flags |= CVMX_USB_INITIALIZE_FLAGS_NO_DMA;
816 usbcx_gahbcfg.u32 = 0;
817 usbcx_gahbcfg.s.dmaen = !(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA);
818 if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
819 usb->idle_hardware_channels = 0x1; /* Only use one channel with non DMA */
820 else if (OCTEON_IS_MODEL(OCTEON_CN5XXX))
821 usb->idle_hardware_channels = 0xf7; /* CN5XXX have an errata with channel 3 */
823 usb->idle_hardware_channels = 0xff;
824 usbcx_gahbcfg.s.hbstlen = 0;
825 usbcx_gahbcfg.s.nptxfemplvl = 1;
826 usbcx_gahbcfg.s.ptxfemplvl = 1;
827 usbcx_gahbcfg.s.glblintrmsk = 1;
828 __cvmx_usb_write_csr32(usb, CVMX_USBCX_GAHBCFG(usb->index),
831 /* 3. Program the following fields in USBC_GUSBCFG register.
832 HS/FS timeout calibration, USBC_GUSBCFG[TOUTCAL] = 0
833 ULPI DDR select, USBC_GUSBCFG[DDRSEL] = 0
834 USB turnaround time, USBC_GUSBCFG[USBTRDTIM] = 0x5
835 PHY low-power clock select, USBC_GUSBCFG[PHYLPWRCLKSEL] = 0 */
837 cvmx_usbcx_gusbcfg_t usbcx_gusbcfg;
838 usbcx_gusbcfg.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GUSBCFG(usb->index));
839 usbcx_gusbcfg.s.toutcal = 0;
840 usbcx_gusbcfg.s.ddrsel = 0;
841 usbcx_gusbcfg.s.usbtrdtim = 0x5;
842 usbcx_gusbcfg.s.phylpwrclksel = 0;
843 __cvmx_usb_write_csr32(usb, CVMX_USBCX_GUSBCFG(usb->index),
846 /* 4. The software must unmask the following bits in the USBC_GINTMSK
848 OTG interrupt mask, USBC_GINTMSK[OTGINTMSK] = 1
849 Mode mismatch interrupt mask, USBC_GINTMSK[MODEMISMSK] = 1 */
851 cvmx_usbcx_gintmsk_t usbcx_gintmsk;
854 usbcx_gintmsk.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GINTMSK(usb->index));
855 usbcx_gintmsk.s.otgintmsk = 1;
856 usbcx_gintmsk.s.modemismsk = 1;
857 usbcx_gintmsk.s.hchintmsk = 1;
858 usbcx_gintmsk.s.sofmsk = 0;
859 /* We need RX FIFO interrupts if we don't have DMA */
860 if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
861 usbcx_gintmsk.s.rxflvlmsk = 1;
862 __cvmx_usb_write_csr32(usb, CVMX_USBCX_GINTMSK(usb->index),
865 /* Disable all channel interrupts. We'll enable them per channel later */
866 for (channel=0; channel<8; channel++)
867 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), 0);
871 /* Host Port Initialization */
872 if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO))
873 cvmx_dprintf("%s: USB%d is in host mode\n", __FUNCTION__, usb->index);
875 /* 1. Program the host-port interrupt-mask field to unmask,
876 USBC_GINTMSK[PRTINT] = 1 */
877 USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), cvmx_usbcx_gintmsk_t,
879 USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), cvmx_usbcx_gintmsk_t,
881 /* 2. Program the USBC_HCFG register to select full-speed host or
884 cvmx_usbcx_hcfg_t usbcx_hcfg;
885 usbcx_hcfg.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCFG(usb->index));
886 usbcx_hcfg.s.fslssupp = 0;
887 usbcx_hcfg.s.fslspclksel = 0;
888 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCFG(usb->index), usbcx_hcfg.u32);
890 /* 3. Program the port power bit to drive VBUS on the USB,
891 USBC_HPRT[PRTPWR] = 1 */
892 USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), cvmx_usbcx_hprt_t, prtpwr, 1);
894 /* Steps 4-15 from the manual are done later in the port enable */
897 #ifdef __CVMX_ERROR_H__
898 cvmx_error_enable_group(CVMX_ERROR_GROUP_USB, usb->index);
900 CVMX_USB_RETURN(CVMX_USB_SUCCESS);
902 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
903 EXPORT_SYMBOL(cvmx_usb_initialize);
908 * Shutdown a USB port after a call to cvmx_usb_initialize().
909 * The port should be disabled with all pipes closed when this
910 * function is called.
912 * @param state USB device state populated by
913 * cvmx_usb_initialize().
915 * @return CVMX_USB_SUCCESS or a negative error code defined in
918 cvmx_usb_status_t cvmx_usb_shutdown(cvmx_usb_state_t *state)
920 cvmx_usbnx_clk_ctl_t usbn_clk_ctl;
921 cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
923 CVMX_USB_LOG_CALLED();
924 CVMX_USB_LOG_PARAM("%p", state);
926 /* Make sure all pipes are closed */
927 if (usb->idle_pipes.head ||
928 usb->active_pipes[CVMX_USB_TRANSFER_ISOCHRONOUS].head ||
929 usb->active_pipes[CVMX_USB_TRANSFER_INTERRUPT].head ||
930 usb->active_pipes[CVMX_USB_TRANSFER_CONTROL].head ||
931 usb->active_pipes[CVMX_USB_TRANSFER_BULK].head)
932 CVMX_USB_RETURN(CVMX_USB_BUSY);
934 #ifdef __CVMX_ERROR_H__
935 cvmx_error_disable_group(CVMX_ERROR_GROUP_USB, usb->index);
938 /* Disable the clocks and put them in power on reset */
939 usbn_clk_ctl.u64 = __cvmx_usb_read_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index));
940 usbn_clk_ctl.s.enable = 1;
941 usbn_clk_ctl.s.por = 1;
942 usbn_clk_ctl.s.hclk_rst = 1;
943 usbn_clk_ctl.s.prst = 0;
944 usbn_clk_ctl.s.hrst = 0;
945 __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
947 CVMX_USB_RETURN(CVMX_USB_SUCCESS);
949 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
950 EXPORT_SYMBOL(cvmx_usb_shutdown);
955 * Enable a USB port. After this call succeeds, the USB port is
956 * online and servicing requests.
958 * @param state USB device state populated by
959 * cvmx_usb_initialize().
961 * @return CVMX_USB_SUCCESS or a negative error code defined in
964 cvmx_usb_status_t cvmx_usb_enable(cvmx_usb_state_t *state)
966 cvmx_usbcx_ghwcfg3_t usbcx_ghwcfg3;
967 cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
969 CVMX_USB_LOG_CALLED();
970 CVMX_USB_LOG_PARAM("%p", state);
972 usb->usbcx_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
974 /* If the port is already enabled the just return. We don't need to do
976 if (usb->usbcx_hprt.s.prtena)
977 CVMX_USB_RETURN(CVMX_USB_SUCCESS);
979 /* If there is nothing plugged into the port then fail immediately */
980 if (!usb->usbcx_hprt.s.prtconnsts)
982 if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO))
983 cvmx_dprintf("%s: USB%d Nothing plugged into the port\n", __FUNCTION__, usb->index);
984 CVMX_USB_RETURN(CVMX_USB_TIMEOUT);
987 /* Program the port reset bit to start the reset process */
988 USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), cvmx_usbcx_hprt_t, prtrst, 1);
990 /* Wait at least 50ms (high speed), or 10ms (full speed) for the reset
991 process to complete. */
992 cvmx_wait_usec(50000);
994 /* Program the port reset bit to 0, USBC_HPRT[PRTRST] = 0 */
995 USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), cvmx_usbcx_hprt_t, prtrst, 0);
997 /* Wait for the USBC_HPRT[PRTENA]. */
998 if (CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_HPRT(usb->index), cvmx_usbcx_hprt_t,
999 prtena, ==, 1, 100000))
1001 if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO))
1002 cvmx_dprintf("%s: Timeout waiting for the port to finish reset\n",
1004 CVMX_USB_RETURN(CVMX_USB_TIMEOUT);
1007 /* Read the port speed field to get the enumerated speed, USBC_HPRT[PRTSPD]. */
1008 usb->usbcx_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
1009 if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO))
1010 cvmx_dprintf("%s: USB%d is in %s speed mode\n", __FUNCTION__, usb->index,
1011 (usb->usbcx_hprt.s.prtspd == CVMX_USB_SPEED_HIGH) ? "high" :
1012 (usb->usbcx_hprt.s.prtspd == CVMX_USB_SPEED_FULL) ? "full" :
1015 usbcx_ghwcfg3.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GHWCFG3(usb->index));
1017 /* 13. Program the USBC_GRXFSIZ register to select the size of the receive
1019 USB_SET_FIELD32(CVMX_USBCX_GRXFSIZ(usb->index), cvmx_usbcx_grxfsiz_t,
1020 rxfdep, usbcx_ghwcfg3.s.dfifodepth / 4);
1021 /* 14. Program the USBC_GNPTXFSIZ register to select the size and the
1022 start address of the non- periodic transmit FIFO for nonperiodic
1023 transactions (50%). */
1025 cvmx_usbcx_gnptxfsiz_t siz;
1026 siz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GNPTXFSIZ(usb->index));
1027 siz.s.nptxfdep = usbcx_ghwcfg3.s.dfifodepth / 2;
1028 siz.s.nptxfstaddr = usbcx_ghwcfg3.s.dfifodepth / 4;
1029 __cvmx_usb_write_csr32(usb, CVMX_USBCX_GNPTXFSIZ(usb->index), siz.u32);
1031 /* 15. Program the USBC_HPTXFSIZ register to select the size and start
1032 address of the periodic transmit FIFO for periodic transactions (25%). */
1034 cvmx_usbcx_hptxfsiz_t siz;
1035 siz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPTXFSIZ(usb->index));
1036 siz.s.ptxfsize = usbcx_ghwcfg3.s.dfifodepth / 4;
1037 siz.s.ptxfstaddr = 3 * usbcx_ghwcfg3.s.dfifodepth / 4;
1038 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HPTXFSIZ(usb->index), siz.u32);
1040 /* Flush all FIFOs */
1041 USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), cvmx_usbcx_grstctl_t, txfnum, 0x10);
1042 USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), cvmx_usbcx_grstctl_t, txfflsh, 1);
1043 CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), cvmx_usbcx_grstctl_t,
1044 txfflsh, ==, 0, 100);
1045 USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), cvmx_usbcx_grstctl_t, rxfflsh, 1);
1046 CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), cvmx_usbcx_grstctl_t,
1047 rxfflsh, ==, 0, 100);
1049 CVMX_USB_RETURN(CVMX_USB_SUCCESS);
1051 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
1052 EXPORT_SYMBOL(cvmx_usb_enable);
1057 * Disable a USB port. After this call the USB port will not
1058 * generate data transfers and will not generate events.
1059 * Transactions in process will fail and call their
1060 * associated callbacks.
1062 * @param state USB device state populated by
1063 * cvmx_usb_initialize().
1065 * @return CVMX_USB_SUCCESS or a negative error code defined in
1066 * cvmx_usb_status_t.
1068 cvmx_usb_status_t cvmx_usb_disable(cvmx_usb_state_t *state)
1070 cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
1072 CVMX_USB_LOG_CALLED();
1073 CVMX_USB_LOG_PARAM("%p", state);
1075 /* Disable the port */
1076 USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), cvmx_usbcx_hprt_t, prtena, 1);
1077 CVMX_USB_RETURN(CVMX_USB_SUCCESS);
1079 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
1080 EXPORT_SYMBOL(cvmx_usb_disable);
1085 * Get the current state of the USB port. Use this call to
1086 * determine if the usb port has anything connected, is enabled,
1087 * or has some sort of error condition. The return value of this
1088 * call has "changed" bits to signal of the value of some fields
1089 * have changed between calls. These "changed" fields are based
1090 * on the last call to cvmx_usb_set_status(). In order to clear
1091 * them, you must update the status through cvmx_usb_set_status().
1093 * @param state USB device state populated by
1094 * cvmx_usb_initialize().
1096 * @return Port status information
1098 cvmx_usb_port_status_t cvmx_usb_get_status(cvmx_usb_state_t *state)
1100 cvmx_usbcx_hprt_t usbc_hprt;
1101 cvmx_usb_port_status_t result;
1102 cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
1104 memset(&result, 0, sizeof(result));
1106 CVMX_USB_LOG_CALLED();
1107 CVMX_USB_LOG_PARAM("%p", state);
1109 usbc_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
1110 result.port_enabled = usbc_hprt.s.prtena;
1111 result.port_over_current = usbc_hprt.s.prtovrcurract;
1112 result.port_powered = usbc_hprt.s.prtpwr;
1113 result.port_speed = usbc_hprt.s.prtspd;
1114 result.connected = usbc_hprt.s.prtconnsts;
1115 result.connect_change = (result.connected != usb->port_status.connected);
1117 if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CALLS))
1118 cvmx_dprintf("%*s%s: returned port enabled=%d, over_current=%d, powered=%d, speed=%d, connected=%d, connect_change=%d\n",
1119 2*(--usb->indent), "", __FUNCTION__,
1120 result.port_enabled,
1121 result.port_over_current,
1122 result.port_powered,
1125 result.connect_change);
1128 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
1129 EXPORT_SYMBOL(cvmx_usb_get_status);
1134 * Set the current state of the USB port. The status is used as
1135 * a reference for the "changed" bits returned by
1136 * cvmx_usb_get_status(). Other than serving as a reference, the
1137 * status passed to this function is not used. No fields can be
1138 * changed through this call.
1140 * @param state USB device state populated by
1141 * cvmx_usb_initialize().
1142 * @param port_status
1143 * Port status to set, most like returned by cvmx_usb_get_status()
1145 void cvmx_usb_set_status(cvmx_usb_state_t *state, cvmx_usb_port_status_t port_status)
1147 cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
1148 CVMX_USB_LOG_CALLED();
1149 CVMX_USB_LOG_PARAM("%p", state);
1150 usb->port_status = port_status;
1151 CVMX_USB_RETURN_NOTHING();
1153 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
1154 EXPORT_SYMBOL(cvmx_usb_set_status);
1160 * Convert a USB transaction into a handle
1162 * @param usb USB device state populated by
1163 * cvmx_usb_initialize().
1164 * @param transaction
1165 * Transaction to get handle for
1169 static inline int __cvmx_usb_get_submit_handle(cvmx_usb_internal_state_t *usb,
1170 cvmx_usb_transaction_t *transaction)
1172 return ((unsigned long)transaction - (unsigned long)usb->transaction) /
1173 sizeof(*transaction);
1179 * Convert a USB pipe into a handle
1181 * @param usb USB device state populated by
1182 * cvmx_usb_initialize().
1183 * @param pipe Pipe to get handle for
1187 static inline int __cvmx_usb_get_pipe_handle(cvmx_usb_internal_state_t *usb,
1188 cvmx_usb_pipe_t *pipe)
1190 return ((unsigned long)pipe - (unsigned long)usb->pipe) / sizeof(*pipe);
1195 * Open a virtual pipe between the host and a USB device. A pipe
1196 * must be opened before data can be transferred between a device
1199 * @param state USB device state populated by
1200 * cvmx_usb_initialize().
1201 * @param flags Optional pipe flags defined in
1202 * cvmx_usb_pipe_flags_t.
1203 * @param device_addr
1204 * USB device address to open the pipe to
1206 * @param endpoint_num
1207 * USB endpoint number to open the pipe to
1209 * @param device_speed
1210 * The speed of the device the pipe is going
1211 * to. This must match the device's speed,
1212 * which may be different than the port speed.
1213 * @param max_packet The maximum packet length the device can
1214 * transmit/receive (low speed=0-8, full
1215 * speed=0-1023, high speed=0-1024). This value
1216 * comes from the standard endpoint descriptor
1217 * field wMaxPacketSize bits <10:0>.
1218 * @param transfer_type
1219 * The type of transfer this pipe is for.
1220 * @param transfer_dir
1221 * The direction the pipe is in. This is not
1222 * used for control pipes.
1223 * @param interval For ISOCHRONOUS and INTERRUPT transfers,
1224 * this is how often the transfer is scheduled
1225 * for. All other transfers should specify
1226 * zero. The units are in frames (8000/sec at
1227 * high speed, 1000/sec for full speed).
1228 * @param multi_count
1229 * For high speed devices, this is the maximum
1230 * allowed number of packet per microframe.
1231 * Specify zero for non high speed devices. This
1232 * value comes from the standard endpoint descriptor
1233 * field wMaxPacketSize bits <12:11>.
1234 * @param hub_device_addr
1235 * Hub device address this device is connected
1236 * to. Devices connected directly to Octeon
1237 * use zero. This is only used when the device
1238 * is full/low speed behind a high speed hub.
1239 * The address will be of the high speed hub,
1240 * not and full speed hubs after it.
1241 * @param hub_port Which port on the hub the device is
1242 * connected. Use zero for devices connected
1243 * directly to Octeon. Like hub_device_addr,
1244 * this is only used for full/low speed
1245 * devices behind a high speed hub.
1247 * @return A non negative value is a pipe handle. Negative
1248 * values are failure codes from cvmx_usb_status_t.
1250 int cvmx_usb_open_pipe(cvmx_usb_state_t *state, cvmx_usb_pipe_flags_t flags,
1251 int device_addr, int endpoint_num,
1252 cvmx_usb_speed_t device_speed, int max_packet,
1253 cvmx_usb_transfer_t transfer_type,
1254 cvmx_usb_direction_t transfer_dir, int interval,
1255 int multi_count, int hub_device_addr, int hub_port)
1257 cvmx_usb_pipe_t *pipe;
1258 cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
1260 CVMX_USB_LOG_CALLED();
1261 CVMX_USB_LOG_PARAM("%p", state);
1262 CVMX_USB_LOG_PARAM("0x%x", flags);
1263 CVMX_USB_LOG_PARAM("%d", device_addr);
1264 CVMX_USB_LOG_PARAM("%d", endpoint_num);
1265 CVMX_USB_LOG_PARAM("%d", device_speed);
1266 CVMX_USB_LOG_PARAM("%d", max_packet);
1267 CVMX_USB_LOG_PARAM("%d", transfer_type);
1268 CVMX_USB_LOG_PARAM("%d", transfer_dir);
1269 CVMX_USB_LOG_PARAM("%d", interval);
1270 CVMX_USB_LOG_PARAM("%d", multi_count);
1271 CVMX_USB_LOG_PARAM("%d", hub_device_addr);
1272 CVMX_USB_LOG_PARAM("%d", hub_port);
1274 if (cvmx_unlikely((device_addr < 0) || (device_addr > MAX_USB_ADDRESS)))
1275 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
1276 if (cvmx_unlikely((endpoint_num < 0) || (endpoint_num > MAX_USB_ENDPOINT)))
1277 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
1278 if (cvmx_unlikely(device_speed > CVMX_USB_SPEED_LOW))
1279 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
1280 if (cvmx_unlikely((max_packet <= 0) || (max_packet > 1024)))
1281 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
1282 if (cvmx_unlikely(transfer_type > CVMX_USB_TRANSFER_INTERRUPT))
1283 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
1284 if (cvmx_unlikely((transfer_dir != CVMX_USB_DIRECTION_OUT) &&
1285 (transfer_dir != CVMX_USB_DIRECTION_IN)))
1286 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
1287 if (cvmx_unlikely(interval < 0))
1288 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
1289 if (cvmx_unlikely((transfer_type == CVMX_USB_TRANSFER_CONTROL) && interval))
1290 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
1291 if (cvmx_unlikely(multi_count < 0))
1292 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
1293 if (cvmx_unlikely((device_speed != CVMX_USB_SPEED_HIGH) &&
1294 (multi_count != 0)))
1295 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
1296 if (cvmx_unlikely((hub_device_addr < 0) || (hub_device_addr > MAX_USB_ADDRESS)))
1297 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
1298 if (cvmx_unlikely((hub_port < 0) || (hub_port > MAX_USB_HUB_PORT)))
1299 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
1301 /* Find a free pipe */
1302 pipe = usb->free_pipes.head;
1304 CVMX_USB_RETURN(CVMX_USB_NO_MEMORY);
1305 __cvmx_usb_remove_pipe(&usb->free_pipes, pipe);
1306 pipe->flags = flags | __CVMX_USB_PIPE_FLAGS_OPEN;
1307 if ((device_speed == CVMX_USB_SPEED_HIGH) &&
1308 (transfer_dir == CVMX_USB_DIRECTION_OUT) &&
1309 (transfer_type == CVMX_USB_TRANSFER_BULK))
1310 pipe->flags |= __CVMX_USB_PIPE_FLAGS_NEED_PING;
1311 pipe->device_addr = device_addr;
1312 pipe->endpoint_num = endpoint_num;
1313 pipe->device_speed = device_speed;
1314 pipe->max_packet = max_packet;
1315 pipe->transfer_type = transfer_type;
1316 pipe->transfer_dir = transfer_dir;
1317 /* All pipes use interval to rate limit NAK processing. Force an interval
1318 if one wasn't supplied */
1321 if (__cvmx_usb_pipe_needs_split(usb, pipe))
1323 pipe->interval = interval*8;
1324 /* Force start splits to be schedule on uFrame 0 */
1325 pipe->next_tx_frame = ((usb->frame_number+7)&~7) + pipe->interval;
1329 pipe->interval = interval;
1330 pipe->next_tx_frame = usb->frame_number + pipe->interval;
1332 pipe->multi_count = multi_count;
1333 pipe->hub_device_addr = hub_device_addr;
1334 pipe->hub_port = hub_port;
1335 pipe->pid_toggle = 0;
1336 pipe->split_sc_frame = -1;
1337 __cvmx_usb_append_pipe(&usb->idle_pipes, pipe);
1339 /* We don't need to tell the hardware about this pipe yet since
1340 it doesn't have any submitted requests */
1342 CVMX_USB_RETURN(__cvmx_usb_get_pipe_handle(usb, pipe));
1344 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
1345 EXPORT_SYMBOL(cvmx_usb_open_pipe);
1351 * Poll the RX FIFOs and remove data as needed. This function is only used
1352 * in non DMA mode. It is very important that this function be called quickly
1353 * enough to prevent FIFO overflow.
1355 * @param usb USB device state populated by
1356 * cvmx_usb_initialize().
1358 static void __cvmx_usb_poll_rx_fifo(cvmx_usb_internal_state_t *usb)
1360 cvmx_usbcx_grxstsph_t rx_status;
1366 CVMX_USB_LOG_CALLED();
1367 CVMX_USB_LOG_PARAM("%p", usb);
1369 rx_status.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GRXSTSPH(usb->index));
1370 /* Only read data if IN data is there */
1371 if (rx_status.s.pktsts != 2)
1372 CVMX_USB_RETURN_NOTHING();
1373 /* Check if no data is available */
1374 if (!rx_status.s.bcnt)
1375 CVMX_USB_RETURN_NOTHING();
1377 channel = rx_status.s.chnum;
1378 bytes = rx_status.s.bcnt;
1380 CVMX_USB_RETURN_NOTHING();
1382 /* Get where the DMA engine would have written this data */
1383 address = __cvmx_usb_read_csr64(usb, CVMX_USBNX_DMA0_INB_CHN0(usb->index) + channel*8);
1384 ptr = cvmx_phys_to_ptr(address);
1385 __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_INB_CHN0(usb->index) + channel*8, address + bytes);
1387 /* Loop writing the FIFO data for this packet into memory */
1390 *ptr++ = __cvmx_usb_read_csr32(usb, USB_FIFO_ADDRESS(channel, usb->index));
1395 CVMX_USB_RETURN_NOTHING();
1400 * Fill the TX hardware fifo with data out of the software
1403 * @param usb USB device state populated by
1404 * cvmx_usb_initialize().
1405 * @param fifo Software fifo to use
1406 * @param available Amount of space in the hardware fifo
1408 * @return Non zero if the hardware fifo was too small and needs
1409 * to be serviced again.
1411 static int __cvmx_usb_fill_tx_hw(cvmx_usb_internal_state_t *usb, cvmx_usb_tx_fifo_t *fifo, int available)
1413 CVMX_USB_LOG_CALLED();
1414 CVMX_USB_LOG_PARAM("%p", usb);
1415 CVMX_USB_LOG_PARAM("%p", fifo);
1416 CVMX_USB_LOG_PARAM("%d", available);
1418 /* We're done either when there isn't anymore space or the software FIFO
1420 while (available && (fifo->head != fifo->tail))
1423 const uint32_t *ptr = cvmx_phys_to_ptr(fifo->entry[i].address);
1424 uint64_t csr_address = USB_FIFO_ADDRESS(fifo->entry[i].channel, usb->index) ^ 4;
1425 int words = available;
1427 /* Limit the amount of data to waht the SW fifo has */
1428 if (fifo->entry[i].size <= available)
1430 words = fifo->entry[i].size;
1432 if (fifo->tail > MAX_CHANNELS)
1436 /* Update the next locations and counts */
1438 fifo->entry[i].address += words * 4;
1439 fifo->entry[i].size -= words;
1441 /* Write the HW fifo data. The read every three writes is due
1442 to an errata on CN3XXX chips */
1445 cvmx_write64_uint32(csr_address, *ptr++);
1446 cvmx_write64_uint32(csr_address, *ptr++);
1447 cvmx_write64_uint32(csr_address, *ptr++);
1448 cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index));
1451 cvmx_write64_uint32(csr_address, *ptr++);
1454 cvmx_write64_uint32(csr_address, *ptr++);
1456 cvmx_write64_uint32(csr_address, *ptr++);
1458 cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index));
1460 CVMX_USB_RETURN(fifo->head != fifo->tail);
1465 * Check the hardware FIFOs and fill them as needed
1467 * @param usb USB device state populated by
1468 * cvmx_usb_initialize().
1470 static void __cvmx_usb_poll_tx_fifo(cvmx_usb_internal_state_t *usb)
1472 CVMX_USB_LOG_CALLED();
1473 CVMX_USB_LOG_PARAM("%p", usb);
1475 if (usb->periodic.head != usb->periodic.tail)
1477 cvmx_usbcx_hptxsts_t tx_status;
1478 tx_status.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPTXSTS(usb->index));
1479 if (__cvmx_usb_fill_tx_hw(usb, &usb->periodic, tx_status.s.ptxfspcavail))
1480 USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), cvmx_usbcx_gintmsk_t, ptxfempmsk, 1);
1482 USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), cvmx_usbcx_gintmsk_t, ptxfempmsk, 0);
1485 if (usb->nonperiodic.head != usb->nonperiodic.tail)
1487 cvmx_usbcx_gnptxsts_t tx_status;
1488 tx_status.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GNPTXSTS(usb->index));
1489 if (__cvmx_usb_fill_tx_hw(usb, &usb->nonperiodic, tx_status.s.nptxfspcavail))
1490 USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), cvmx_usbcx_gintmsk_t, nptxfempmsk, 1);
1492 USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), cvmx_usbcx_gintmsk_t, nptxfempmsk, 0);
1495 CVMX_USB_RETURN_NOTHING();
1501 * Fill the TX FIFO with an outgoing packet
1503 * @param usb USB device state populated by
1504 * cvmx_usb_initialize().
1505 * @param channel Channel number to get packet from
1507 static void __cvmx_usb_fill_tx_fifo(cvmx_usb_internal_state_t *usb, int channel)
1509 cvmx_usbcx_hccharx_t hcchar;
1510 cvmx_usbcx_hcspltx_t usbc_hcsplt;
1511 cvmx_usbcx_hctsizx_t usbc_hctsiz;
1512 cvmx_usb_tx_fifo_t *fifo;
1514 CVMX_USB_LOG_CALLED();
1515 CVMX_USB_LOG_PARAM("%p", usb);
1516 CVMX_USB_LOG_PARAM("%d", channel);
1518 /* We only need to fill data on outbound channels */
1519 hcchar.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index));
1520 if (hcchar.s.epdir != CVMX_USB_DIRECTION_OUT)
1521 CVMX_USB_RETURN_NOTHING();
1523 /* OUT Splits only have data on the start and not the complete */
1524 usbc_hcsplt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCSPLTX(channel, usb->index));
1525 if (usbc_hcsplt.s.spltena && usbc_hcsplt.s.compsplt)
1526 CVMX_USB_RETURN_NOTHING();
1528 /* Find out how many bytes we need to fill and convert it into 32bit words */
1529 usbc_hctsiz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index));
1530 if (!usbc_hctsiz.s.xfersize)
1531 CVMX_USB_RETURN_NOTHING();
1533 if ((hcchar.s.eptype == CVMX_USB_TRANSFER_INTERRUPT) ||
1534 (hcchar.s.eptype == CVMX_USB_TRANSFER_ISOCHRONOUS))
1535 fifo = &usb->periodic;
1537 fifo = &usb->nonperiodic;
1539 fifo->entry[fifo->head].channel = channel;
1540 fifo->entry[fifo->head].address = __cvmx_usb_read_csr64(usb, CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8);
1541 fifo->entry[fifo->head].size = (usbc_hctsiz.s.xfersize+3)>>2;
1543 if (fifo->head > MAX_CHANNELS)
1546 __cvmx_usb_poll_tx_fifo(usb);
1548 CVMX_USB_RETURN_NOTHING();
1553 * Perform channel specific setup for Control transactions. All
1554 * the generic stuff will already have been done in
1555 * __cvmx_usb_start_channel()
1557 * @param usb USB device state populated by
1558 * cvmx_usb_initialize().
1559 * @param channel Channel to setup
1560 * @param pipe Pipe for control transaction
1562 static void __cvmx_usb_start_channel_control(cvmx_usb_internal_state_t *usb,
1564 cvmx_usb_pipe_t *pipe)
1566 cvmx_usb_transaction_t *transaction = pipe->head;
1567 cvmx_usb_control_header_t *header = cvmx_phys_to_ptr(transaction->control_header);
1568 int bytes_to_transfer = transaction->buffer_length - transaction->actual_bytes;
1569 int packets_to_transfer;
1570 cvmx_usbcx_hctsizx_t usbc_hctsiz;
1572 CVMX_USB_LOG_CALLED();
1573 CVMX_USB_LOG_PARAM("%p", usb);
1574 CVMX_USB_LOG_PARAM("%d", channel);
1575 CVMX_USB_LOG_PARAM("%p", pipe);
1577 usbc_hctsiz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index));
1579 switch (transaction->stage)
1581 case CVMX_USB_STAGE_NON_CONTROL:
1582 case CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE:
1583 cvmx_dprintf("%s: ERROR - Non control stage\n", __FUNCTION__);
1585 case CVMX_USB_STAGE_SETUP:
1586 usbc_hctsiz.s.pid = 3; /* Setup */
1587 bytes_to_transfer = sizeof(*header);
1588 /* All Control operations start with a setup going OUT */
1589 USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), cvmx_usbcx_hccharx_t, epdir, CVMX_USB_DIRECTION_OUT);
1590 /* Setup send the control header instead of the buffer data. The
1591 buffer data will be used in the next stage */
1592 __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8, transaction->control_header);
1594 case CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE:
1595 usbc_hctsiz.s.pid = 3; /* Setup */
1596 bytes_to_transfer = 0;
1597 /* All Control operations start with a setup going OUT */
1598 USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), cvmx_usbcx_hccharx_t, epdir, CVMX_USB_DIRECTION_OUT);
1599 USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index), cvmx_usbcx_hcspltx_t, compsplt, 1);
1601 case CVMX_USB_STAGE_DATA:
1602 usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
1603 if (__cvmx_usb_pipe_needs_split(usb, pipe))
1605 if (header->s.request_type & 0x80)
1606 bytes_to_transfer = 0;
1607 else if (bytes_to_transfer > pipe->max_packet)
1608 bytes_to_transfer = pipe->max_packet;
1610 USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
1611 cvmx_usbcx_hccharx_t, epdir,
1612 ((header->s.request_type & 0x80) ?
1613 CVMX_USB_DIRECTION_IN :
1614 CVMX_USB_DIRECTION_OUT));
1616 case CVMX_USB_STAGE_DATA_SPLIT_COMPLETE:
1617 usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
1618 if (!(header->s.request_type & 0x80))
1619 bytes_to_transfer = 0;
1620 USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
1621 cvmx_usbcx_hccharx_t, epdir,
1622 ((header->s.request_type & 0x80) ?
1623 CVMX_USB_DIRECTION_IN :
1624 CVMX_USB_DIRECTION_OUT));
1625 USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index), cvmx_usbcx_hcspltx_t, compsplt, 1);
1627 case CVMX_USB_STAGE_STATUS:
1628 usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
1629 bytes_to_transfer = 0;
1630 USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), cvmx_usbcx_hccharx_t, epdir,
1631 ((header->s.request_type & 0x80) ?
1632 CVMX_USB_DIRECTION_OUT :
1633 CVMX_USB_DIRECTION_IN));
1635 case CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE:
1636 usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
1637 bytes_to_transfer = 0;
1638 USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), cvmx_usbcx_hccharx_t, epdir,
1639 ((header->s.request_type & 0x80) ?
1640 CVMX_USB_DIRECTION_OUT :
1641 CVMX_USB_DIRECTION_IN));
1642 USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index), cvmx_usbcx_hcspltx_t, compsplt, 1);
1646 /* Make sure the transfer never exceeds the byte limit of the hardware.
1647 Further bytes will be sent as continued transactions */
1648 if (bytes_to_transfer > MAX_TRANSFER_BYTES)
1650 /* Round MAX_TRANSFER_BYTES to a multiple of out packet size */
1651 bytes_to_transfer = MAX_TRANSFER_BYTES / pipe->max_packet;
1652 bytes_to_transfer *= pipe->max_packet;
1655 /* Calculate the number of packets to transfer. If the length is zero
1656 we still need to transfer one packet */
1657 packets_to_transfer = (bytes_to_transfer + pipe->max_packet - 1) / pipe->max_packet;
1658 if (packets_to_transfer == 0)
1659 packets_to_transfer = 1;
1660 else if ((packets_to_transfer>1) && (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA))
1662 /* Limit to one packet when not using DMA. Channels must be restarted
1663 between every packet for IN transactions, so there is no reason to
1664 do multiple packets in a row */
1665 packets_to_transfer = 1;
1666 bytes_to_transfer = packets_to_transfer * pipe->max_packet;
1668 else if (packets_to_transfer > MAX_TRANSFER_PACKETS)
1670 /* Limit the number of packet and data transferred to what the
1671 hardware can handle */
1672 packets_to_transfer = MAX_TRANSFER_PACKETS;
1673 bytes_to_transfer = packets_to_transfer * pipe->max_packet;
1676 usbc_hctsiz.s.xfersize = bytes_to_transfer;
1677 usbc_hctsiz.s.pktcnt = packets_to_transfer;
1679 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index), usbc_hctsiz.u32);
1680 CVMX_USB_RETURN_NOTHING();
1686 * Start a channel to perform the pipe's head transaction
1688 * @param usb USB device state populated by
1689 * cvmx_usb_initialize().
1690 * @param channel Channel to setup
1691 * @param pipe Pipe to start
1693 static void __cvmx_usb_start_channel(cvmx_usb_internal_state_t *usb,
1695 cvmx_usb_pipe_t *pipe)
1697 cvmx_usb_transaction_t *transaction = pipe->head;
1699 CVMX_USB_LOG_CALLED();
1700 CVMX_USB_LOG_PARAM("%p", usb);
1701 CVMX_USB_LOG_PARAM("%d", channel);
1702 CVMX_USB_LOG_PARAM("%p", pipe);
1704 if (cvmx_unlikely((usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_TRANSFERS) ||
1705 (pipe->flags & CVMX_USB_PIPE_FLAGS_DEBUG_TRANSFERS)))
1706 cvmx_dprintf("%s: Channel %d started. Pipe %d transaction %d stage %d\n",
1707 __FUNCTION__, channel, __cvmx_usb_get_pipe_handle(usb, pipe),
1708 __cvmx_usb_get_submit_handle(usb, transaction),
1709 transaction->stage);
1711 /* Make sure all writes to the DMA region get flushed */
1714 /* Attach the channel to the pipe */
1715 usb->pipe_for_channel[channel] = pipe;
1716 pipe->channel = channel;
1717 pipe->flags |= __CVMX_USB_PIPE_FLAGS_SCHEDULED;
1719 /* Mark this channel as in use */
1720 usb->idle_hardware_channels &= ~(1<<channel);
1722 /* Enable the channel interrupt bits */
1724 cvmx_usbcx_hcintx_t usbc_hcint;
1725 cvmx_usbcx_hcintmskx_t usbc_hcintmsk;
1726 cvmx_usbcx_haintmsk_t usbc_haintmsk;
1728 /* Clear all channel status bits */
1729 usbc_hcint.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCINTX(channel, usb->index));
1730 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTX(channel, usb->index), usbc_hcint.u32);
1732 usbc_hcintmsk.u32 = 0;
1733 usbc_hcintmsk.s.chhltdmsk = 1;
1734 if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
1736 /* Channels need these extra interrupts when we aren't in DMA mode */
1737 usbc_hcintmsk.s.datatglerrmsk = 1;
1738 usbc_hcintmsk.s.frmovrunmsk = 1;
1739 usbc_hcintmsk.s.bblerrmsk = 1;
1740 usbc_hcintmsk.s.xacterrmsk = 1;
1741 if (__cvmx_usb_pipe_needs_split(usb, pipe))
1743 /* Splits don't generate xfercompl, so we need ACK and NYET */
1744 usbc_hcintmsk.s.nyetmsk = 1;
1745 usbc_hcintmsk.s.ackmsk = 1;
1747 usbc_hcintmsk.s.nakmsk = 1;
1748 usbc_hcintmsk.s.stallmsk = 1;
1749 usbc_hcintmsk.s.xfercomplmsk = 1;
1751 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), usbc_hcintmsk.u32);
1753 /* Enable the channel interrupt to propagate */
1754 usbc_haintmsk.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HAINTMSK(usb->index));
1755 usbc_haintmsk.s.haintmsk |= 1<<channel;
1756 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HAINTMSK(usb->index), usbc_haintmsk.u32);
1759 /* Setup the locations the DMA engines use */
1761 uint64_t dma_address = transaction->buffer + transaction->actual_bytes;
1762 if (transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS)
1763 dma_address = transaction->buffer + transaction->iso_packets[0].offset + transaction->actual_bytes;
1764 __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8, dma_address);
1765 __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_INB_CHN0(usb->index) + channel*8, dma_address);
1768 /* Setup both the size of the transfer and the SPLIT characteristics */
1770 cvmx_usbcx_hcspltx_t usbc_hcsplt = {.u32 = 0};
1771 cvmx_usbcx_hctsizx_t usbc_hctsiz = {.u32 = 0};
1772 int packets_to_transfer;
1773 int bytes_to_transfer = transaction->buffer_length - transaction->actual_bytes;
1775 /* ISOCHRONOUS transactions store each individual transfer size in the
1776 packet structure, not the global buffer_length */
1777 if (transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS)
1778 bytes_to_transfer = transaction->iso_packets[0].length - transaction->actual_bytes;
1780 /* We need to do split transactions when we are talking to non high
1781 speed devices that are behind a high speed hub */
1782 if (__cvmx_usb_pipe_needs_split(usb, pipe))
1784 /* On the start split phase (stage is even) record the frame number we
1785 will need to send the split complete. We only store the lower two bits
1786 since the time ahead can only be two frames */
1787 if ((transaction->stage&1) == 0)
1789 if (transaction->type == CVMX_USB_TRANSFER_BULK)
1790 pipe->split_sc_frame = (usb->frame_number + 1) & 0x7f;
1792 pipe->split_sc_frame = (usb->frame_number + 2) & 0x7f;
1795 pipe->split_sc_frame = -1;
1797 usbc_hcsplt.s.spltena = 1;
1798 usbc_hcsplt.s.hubaddr = pipe->hub_device_addr;
1799 usbc_hcsplt.s.prtaddr = pipe->hub_port;
1800 usbc_hcsplt.s.compsplt = (transaction->stage == CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE);
1802 /* SPLIT transactions can only ever transmit one data packet so
1803 limit the transfer size to the max packet size */
1804 if (bytes_to_transfer > pipe->max_packet)
1805 bytes_to_transfer = pipe->max_packet;
1807 /* ISOCHRONOUS OUT splits are unique in that they limit
1808 data transfers to 188 byte chunks representing the
1809 begin/middle/end of the data or all */
1810 if (!usbc_hcsplt.s.compsplt &&
1811 (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) &&
1812 (pipe->transfer_type == CVMX_USB_TRANSFER_ISOCHRONOUS))
1814 /* Clear the split complete frame number as there isn't going
1815 to be a split complete */
1816 pipe->split_sc_frame = -1;
1817 /* See if we've started this transfer and sent data */
1818 if (transaction->actual_bytes == 0)
1820 /* Nothing sent yet, this is either a begin or the
1822 if (bytes_to_transfer <= 188)
1823 usbc_hcsplt.s.xactpos = 3; /* Entire payload in one go */
1825 usbc_hcsplt.s.xactpos = 2; /* First part of payload */
1829 /* Continuing the previous data, we must either be
1830 in the middle or at the end */
1831 if (bytes_to_transfer <= 188)
1832 usbc_hcsplt.s.xactpos = 1; /* End of payload */
1834 usbc_hcsplt.s.xactpos = 0; /* Middle of payload */
1836 /* Again, the transfer size is limited to 188 bytes */
1837 if (bytes_to_transfer > 188)
1838 bytes_to_transfer = 188;
1842 /* Make sure the transfer never exceeds the byte limit of the hardware.
1843 Further bytes will be sent as continued transactions */
1844 if (bytes_to_transfer > MAX_TRANSFER_BYTES)
1846 /* Round MAX_TRANSFER_BYTES to a multiple of out packet size */
1847 bytes_to_transfer = MAX_TRANSFER_BYTES / pipe->max_packet;
1848 bytes_to_transfer *= pipe->max_packet;
1851 /* Calculate the number of packets to transfer. If the length is zero
1852 we still need to transfer one packet */
1853 packets_to_transfer = (bytes_to_transfer + pipe->max_packet - 1) / pipe->max_packet;
1854 if (packets_to_transfer == 0)
1855 packets_to_transfer = 1;
1856 else if ((packets_to_transfer>1) && (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA))
1858 /* Limit to one packet when not using DMA. Channels must be restarted
1859 between every packet for IN transactions, so there is no reason to
1860 do multiple packets in a row */
1861 packets_to_transfer = 1;
1862 bytes_to_transfer = packets_to_transfer * pipe->max_packet;
1864 else if (packets_to_transfer > MAX_TRANSFER_PACKETS)
1866 /* Limit the number of packet and data transferred to what the
1867 hardware can handle */
1868 packets_to_transfer = MAX_TRANSFER_PACKETS;
1869 bytes_to_transfer = packets_to_transfer * pipe->max_packet;
1872 usbc_hctsiz.s.xfersize = bytes_to_transfer;
1873 usbc_hctsiz.s.pktcnt = packets_to_transfer;
1875 /* Update the DATA0/DATA1 toggle */
1876 usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
1877 /* High speed pipes may need a hardware ping before they start */
1878 if (pipe->flags & __CVMX_USB_PIPE_FLAGS_NEED_PING)
1879 usbc_hctsiz.s.dopng = 1;
1881 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCSPLTX(channel, usb->index), usbc_hcsplt.u32);
1882 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index), usbc_hctsiz.u32);
1885 /* Setup the Host Channel Characteristics Register */
1887 cvmx_usbcx_hccharx_t usbc_hcchar = {.u32 = 0};
1889 /* Set the startframe odd/even properly. This is only used for periodic */
1890 usbc_hcchar.s.oddfrm = usb->frame_number&1;
1892 /* Set the number of back to back packets allowed by this endpoint.
1893 Split transactions interpret "ec" as the number of immediate
1894 retries of failure. These retries happen too quickly, so we
1895 disable these entirely for splits */
1896 if (__cvmx_usb_pipe_needs_split(usb, pipe))
1897 usbc_hcchar.s.ec = 1;
1898 else if (pipe->multi_count < 1)
1899 usbc_hcchar.s.ec = 1;
1900 else if (pipe->multi_count > 3)
1901 usbc_hcchar.s.ec = 3;
1903 usbc_hcchar.s.ec = pipe->multi_count;
1905 /* Set the rest of the endpoint specific settings */
1906 usbc_hcchar.s.devaddr = pipe->device_addr;
1907 usbc_hcchar.s.eptype = transaction->type;
1908 usbc_hcchar.s.lspddev = (pipe->device_speed == CVMX_USB_SPEED_LOW);
1909 usbc_hcchar.s.epdir = pipe->transfer_dir;
1910 usbc_hcchar.s.epnum = pipe->endpoint_num;
1911 usbc_hcchar.s.mps = pipe->max_packet;
1912 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index), usbc_hcchar.u32);
1915 /* Do transaction type specific fixups as needed */
1916 switch (transaction->type)
1918 case CVMX_USB_TRANSFER_CONTROL:
1919 __cvmx_usb_start_channel_control(usb, channel, pipe);
1921 case CVMX_USB_TRANSFER_BULK:
1922 case CVMX_USB_TRANSFER_INTERRUPT:
1924 case CVMX_USB_TRANSFER_ISOCHRONOUS:
1925 if (!__cvmx_usb_pipe_needs_split(usb, pipe))
1927 /* ISO transactions require different PIDs depending on direction
1928 and how many packets are needed */
1929 if (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT)
1931 if (pipe->multi_count < 2) /* Need DATA0 */
1932 USB_SET_FIELD32(CVMX_USBCX_HCTSIZX(channel, usb->index), cvmx_usbcx_hctsizx_t, pid, 0);
1933 else /* Need MDATA */
1934 USB_SET_FIELD32(CVMX_USBCX_HCTSIZX(channel, usb->index), cvmx_usbcx_hctsizx_t, pid, 3);
1940 cvmx_usbcx_hctsizx_t usbc_hctsiz = {.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index))};
1941 transaction->xfersize = usbc_hctsiz.s.xfersize;
1942 transaction->pktcnt = usbc_hctsiz.s.pktcnt;
1944 /* Remeber when we start a split transaction */
1945 if (__cvmx_usb_pipe_needs_split(usb, pipe))
1946 usb->active_split = transaction;
1947 USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), cvmx_usbcx_hccharx_t, chena, 1);
1948 if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
1949 __cvmx_usb_fill_tx_fifo(usb, channel);
1950 CVMX_USB_RETURN_NOTHING();
1956 * Find a pipe that is ready to be scheduled to hardware.
1957 * @param usb USB device state populated by
1958 * cvmx_usb_initialize().
1959 * @param list Pipe list to search
1960 * @param current_frame
1961 * Frame counter to use as a time reference.
1963 * @return Pipe or NULL if none are ready
1965 static 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)
1967 cvmx_usb_pipe_t *pipe = list->head;
1970 if (!(pipe->flags & __CVMX_USB_PIPE_FLAGS_SCHEDULED) && pipe->head &&
1971 (pipe->next_tx_frame <= current_frame) &&
1972 ((pipe->split_sc_frame == -1) || ((((int)current_frame - (int)pipe->split_sc_frame) & 0x7f) < 0x40)) &&
1973 (!usb->active_split || (usb->active_split == pipe->head)))
1975 CVMX_PREFETCH(pipe, 128);
1976 CVMX_PREFETCH(pipe->head, 0);
1987 * Called whenever a pipe might need to be scheduled to the
1990 * @param usb USB device state populated by
1991 * cvmx_usb_initialize().
1992 * @param is_sof True if this schedule was called on a SOF interrupt.
1994 static void __cvmx_usb_schedule(cvmx_usb_internal_state_t *usb, int is_sof)
1997 cvmx_usb_pipe_t *pipe;
1999 cvmx_usb_transfer_t ttype;
2001 CVMX_USB_LOG_CALLED();
2002 CVMX_USB_LOG_PARAM("%p", usb);
2004 if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
2006 /* Without DMA we need to be careful to not schedule something at the end of a frame and cause an overrun */
2007 cvmx_usbcx_hfnum_t hfnum = {.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index))};
2008 cvmx_usbcx_hfir_t hfir = {.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFIR(usb->index))};
2009 if (hfnum.s.frrem < hfir.s.frint/4)
2013 while (usb->idle_hardware_channels)
2015 /* Find an idle channel */
2016 CVMX_CLZ(channel, usb->idle_hardware_channels);
2017 channel = 31 - channel;
2018 if (cvmx_unlikely(channel > 7))
2020 if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO))
2021 cvmx_dprintf("%s: Idle hardware channels has a channel higher than 7. This is wrong\n", __FUNCTION__);
2025 /* Find a pipe needing service */
2029 /* Only process periodic pipes on SOF interrupts. This way we are
2030 sure that the periodic data is sent in the beginning of the
2032 pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_ISOCHRONOUS, usb->frame_number);
2033 if (cvmx_likely(!pipe))
2034 pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_INTERRUPT, usb->frame_number);
2036 if (cvmx_likely(!pipe))
2038 pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_CONTROL, usb->frame_number);
2039 if (cvmx_likely(!pipe))
2040 pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_BULK, usb->frame_number);
2045 CVMX_USB_LOG_PARAM("%d", channel);
2046 CVMX_USB_LOG_PARAM("%p", pipe);
2048 if (cvmx_unlikely((usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_TRANSFERS) ||
2049 (pipe->flags & CVMX_USB_PIPE_FLAGS_DEBUG_TRANSFERS)))
2051 cvmx_usb_transaction_t *transaction = pipe->head;
2052 const cvmx_usb_control_header_t *header = (transaction->control_header) ? cvmx_phys_to_ptr(transaction->control_header) : NULL;
2053 const char *dir = (pipe->transfer_dir == CVMX_USB_DIRECTION_IN) ? "IN" : "OUT";
2055 switch (pipe->transfer_type)
2057 case CVMX_USB_TRANSFER_CONTROL:
2059 dir = (header->s.request_type & 0x80) ? "IN" : "OUT";
2061 case CVMX_USB_TRANSFER_ISOCHRONOUS:
2062 type = "ISOCHRONOUS";
2064 case CVMX_USB_TRANSFER_BULK:
2067 default: /* CVMX_USB_TRANSFER_INTERRUPT */
2071 cvmx_dprintf("%s: Starting pipe %d, transaction %d on channel %d. %s %s len=%d header=0x%llx\n",
2072 __FUNCTION__, __cvmx_usb_get_pipe_handle(usb, pipe),
2073 __cvmx_usb_get_submit_handle(usb, transaction),
2075 transaction->buffer_length,
2076 (header) ? (unsigned long long)header->u64 : 0ull);
2078 __cvmx_usb_start_channel(usb, channel, pipe);
2082 /* Only enable SOF interrupts when we have transactions pending in the
2083 future that might need to be scheduled */
2085 for (ttype=CVMX_USB_TRANSFER_CONTROL; ttype<=CVMX_USB_TRANSFER_INTERRUPT; ttype++)
2087 pipe = usb->active_pipes[ttype].head;
2090 if (pipe->next_tx_frame > usb->frame_number)
2098 USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), cvmx_usbcx_gintmsk_t, sofmsk, need_sof);
2099 CVMX_USB_RETURN_NOTHING();
2105 * Call a user's callback for a specific reason.
2107 * @param usb USB device state populated by
2108 * cvmx_usb_initialize().
2109 * @param pipe Pipe the callback is for or NULL
2110 * @param transaction
2111 * Transaction the callback is for or NULL
2112 * @param reason Reason this callback is being called
2113 * @param complete_code
2114 * Completion code for the transaction, if any
2116 static void __cvmx_usb_perform_callback(cvmx_usb_internal_state_t *usb,
2117 cvmx_usb_pipe_t *pipe,
2118 cvmx_usb_transaction_t *transaction,
2119 cvmx_usb_callback_t reason,
2120 cvmx_usb_complete_t complete_code)
2122 cvmx_usb_callback_func_t callback = usb->callback[reason];
2123 void *user_data = usb->callback_data[reason];
2124 int submit_handle = -1;
2125 int pipe_handle = -1;
2126 int bytes_transferred = 0;
2129 pipe_handle = __cvmx_usb_get_pipe_handle(usb, pipe);
2133 submit_handle = __cvmx_usb_get_submit_handle(usb, transaction);
2134 bytes_transferred = transaction->actual_bytes;
2135 /* Transactions are allowed to override the default callback */
2136 if ((reason == CVMX_USB_CALLBACK_TRANSFER_COMPLETE) && transaction->callback)
2138 callback = transaction->callback;
2139 user_data = transaction->callback_data;
2146 if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CALLBACKS))
2147 cvmx_dprintf("%*s%s: calling callback %p(usb=%p, complete_code=%s, "
2148 "pipe_handle=%d, submit_handle=%d, bytes_transferred=%d, user_data=%p);\n",
2149 2*usb->indent, "", __FUNCTION__, callback, usb,
2150 __cvmx_usb_complete_to_string(complete_code),
2151 pipe_handle, submit_handle, bytes_transferred, user_data);
2153 callback((cvmx_usb_state_t *)usb, reason, complete_code, pipe_handle, submit_handle,
2154 bytes_transferred, user_data);
2156 if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CALLBACKS))
2157 cvmx_dprintf("%*s%s: callback %p complete\n", 2*usb->indent, "",
2158 __FUNCTION__, callback);
2164 * Signal the completion of a transaction and free it. The
2165 * transaction will be removed from the pipe transaction list.
2167 * @param usb USB device state populated by
2168 * cvmx_usb_initialize().
2169 * @param pipe Pipe the transaction is on
2170 * @param transaction
2171 * Transaction that completed
2172 * @param complete_code
2175 static void __cvmx_usb_perform_complete(cvmx_usb_internal_state_t * usb,
2176 cvmx_usb_pipe_t *pipe,
2177 cvmx_usb_transaction_t *transaction,
2178 cvmx_usb_complete_t complete_code)
2180 CVMX_USB_LOG_CALLED();
2181 CVMX_USB_LOG_PARAM("%p", usb);
2182 CVMX_USB_LOG_PARAM("%p", pipe);
2183 CVMX_USB_LOG_PARAM("%p", transaction);
2184 CVMX_USB_LOG_PARAM("%d", complete_code);
2186 /* If this was a split then clear our split in progress marker */
2187 if (usb->active_split == transaction)
2188 usb->active_split = NULL;
2190 /* Isochronous transactions need extra processing as they might not be done
2191 after a single data transfer */
2192 if (cvmx_unlikely(transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS))
2194 /* Update the number of bytes transferred in this ISO packet */
2195 transaction->iso_packets[0].length = transaction->actual_bytes;
2196 transaction->iso_packets[0].status = complete_code;
2198 /* If there are more ISOs pending and we succeeded, schedule the next
2200 if ((transaction->iso_number_packets > 1) && (complete_code == CVMX_USB_COMPLETE_SUCCESS))
2202 transaction->actual_bytes = 0; /* No bytes transferred for this packet as of yet */
2203 transaction->iso_number_packets--; /* One less ISO waiting to transfer */
2204 transaction->iso_packets++; /* Increment to the next location in our packet array */
2205 transaction->stage = CVMX_USB_STAGE_NON_CONTROL;
2210 /* Remove the transaction from the pipe list */
2211 if (transaction->next)
2212 transaction->next->prev = transaction->prev;
2214 pipe->tail = transaction->prev;
2215 if (transaction->prev)
2216 transaction->prev->next = transaction->next;
2218 pipe->head = transaction->next;
2221 __cvmx_usb_remove_pipe(usb->active_pipes + pipe->transfer_type, pipe);
2222 __cvmx_usb_append_pipe(&usb->idle_pipes, pipe);
2225 __cvmx_usb_perform_callback(usb, pipe, transaction,
2226 CVMX_USB_CALLBACK_TRANSFER_COMPLETE,
2228 __cvmx_usb_free_transaction(usb, transaction);
2230 CVMX_USB_RETURN_NOTHING();
2236 * Submit a usb transaction to a pipe. Called for all types
2240 * @param pipe_handle
2241 * Which pipe to submit to. Will be validated in this function.
2242 * @param type Transaction type
2243 * @param flags Flags for the transaction
2244 * @param buffer User buffer for the transaction
2245 * @param buffer_length
2246 * User buffer's length in bytes
2247 * @param control_header
2248 * For control transactions, the 8 byte standard header
2249 * @param iso_start_frame
2250 * For ISO transactions, the start frame
2251 * @param iso_number_packets
2252 * For ISO, the number of packet in the transaction.
2253 * @param iso_packets
2254 * A description of each ISO packet
2255 * @param callback User callback to call when the transaction completes
2256 * @param user_data User's data for the callback
2258 * @return Submit handle or negative on failure. Matches the result
2259 * in the external API.
2261 static int __cvmx_usb_submit_transaction(cvmx_usb_internal_state_t *usb,
2263 cvmx_usb_transfer_t type,
2267 uint64_t control_header,
2268 int iso_start_frame,
2269 int iso_number_packets,
2270 cvmx_usb_iso_packet_t *iso_packets,
2271 cvmx_usb_callback_func_t callback,
2275 cvmx_usb_transaction_t *transaction;
2276 cvmx_usb_pipe_t *pipe = usb->pipe + pipe_handle;
2278 CVMX_USB_LOG_CALLED();
2279 if (cvmx_unlikely((pipe_handle < 0) || (pipe_handle >= MAX_PIPES)))
2280 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2281 /* Fail if the pipe isn't open */
2282 if (cvmx_unlikely((pipe->flags & __CVMX_USB_PIPE_FLAGS_OPEN) == 0))
2283 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2284 if (cvmx_unlikely(pipe->transfer_type != type))
2285 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2287 transaction = __cvmx_usb_alloc_transaction(usb);
2288 if (cvmx_unlikely(!transaction))
2289 CVMX_USB_RETURN(CVMX_USB_NO_MEMORY);
2291 transaction->type = type;
2292 transaction->flags |= flags;
2293 transaction->buffer = buffer;
2294 transaction->buffer_length = buffer_length;
2295 transaction->control_header = control_header;
2296 transaction->iso_start_frame = iso_start_frame; // FIXME: This is not used, implement it
2297 transaction->iso_number_packets = iso_number_packets;
2298 transaction->iso_packets = iso_packets;
2299 transaction->callback = callback;
2300 transaction->callback_data = user_data;
2301 if (transaction->type == CVMX_USB_TRANSFER_CONTROL)
2302 transaction->stage = CVMX_USB_STAGE_SETUP;
2304 transaction->stage = CVMX_USB_STAGE_NON_CONTROL;
2306 transaction->next = NULL;
2309 transaction->prev = pipe->tail;
2310 transaction->prev->next = transaction;
2314 if (pipe->next_tx_frame < usb->frame_number)
2315 pipe->next_tx_frame = usb->frame_number + pipe->interval -
2316 (usb->frame_number - pipe->next_tx_frame) % pipe->interval;
2317 transaction->prev = NULL;
2318 pipe->head = transaction;
2319 __cvmx_usb_remove_pipe(&usb->idle_pipes, pipe);
2320 __cvmx_usb_append_pipe(usb->active_pipes + pipe->transfer_type, pipe);
2322 pipe->tail = transaction;
2324 submit_handle = __cvmx_usb_get_submit_handle(usb, transaction);
2326 /* We may need to schedule the pipe if this was the head of the pipe */
2327 if (!transaction->prev)
2328 __cvmx_usb_schedule(usb, 0);
2330 CVMX_USB_RETURN(submit_handle);
2335 * Call to submit a USB Bulk transfer to a pipe.
2337 * @param state USB device state populated by
2338 * cvmx_usb_initialize().
2339 * @param pipe_handle
2340 * Handle to the pipe for the transfer.
2341 * @param buffer Physical address of the data buffer in
2342 * memory. Note that this is NOT A POINTER, but
2343 * the full 64bit physical address of the
2344 * buffer. This may be zero if buffer_length is
2346 * @param buffer_length
2347 * Length of buffer in bytes.
2348 * @param callback Function to call when this transaction
2349 * completes. If the return value of this
2350 * function isn't an error, then this function
2351 * is guaranteed to be called when the
2352 * transaction completes. If this parameter is
2353 * NULL, then the generic callback registered
2354 * through cvmx_usb_register_callback is
2355 * called. If both are NULL, then there is no
2356 * way to know when a transaction completes.
2357 * @param user_data User supplied data returned when the
2358 * callback is called. This is only used if
2359 * callback in not NULL.
2361 * @return A submitted transaction handle or negative on
2362 * failure. Negative values are failure codes from
2363 * cvmx_usb_status_t.
2365 int cvmx_usb_submit_bulk(cvmx_usb_state_t *state, int pipe_handle,
2366 uint64_t buffer, int buffer_length,
2367 cvmx_usb_callback_func_t callback,
2371 cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
2373 CVMX_USB_LOG_CALLED();
2374 CVMX_USB_LOG_PARAM("%p", state);
2375 CVMX_USB_LOG_PARAM("%d", pipe_handle);
2376 CVMX_USB_LOG_PARAM("0x%llx", (unsigned long long)buffer);
2377 CVMX_USB_LOG_PARAM("%d", buffer_length);
2379 /* Pipe handle checking is done later in a common place */
2380 if (cvmx_unlikely(!buffer))
2381 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2382 if (cvmx_unlikely(buffer_length < 0))
2383 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2385 submit_handle = __cvmx_usb_submit_transaction(usb, pipe_handle,
2386 CVMX_USB_TRANSFER_BULK,
2390 0, /* control_header */
2391 0, /* iso_start_frame */
2392 0, /* iso_number_packets */
2393 NULL, /* iso_packets */
2396 CVMX_USB_RETURN(submit_handle);
2398 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
2399 EXPORT_SYMBOL(cvmx_usb_submit_bulk);
2404 * Call to submit a USB Interrupt transfer to a pipe.
2406 * @param state USB device state populated by
2407 * cvmx_usb_initialize().
2408 * @param pipe_handle
2409 * Handle to the pipe for the transfer.
2410 * @param buffer Physical address of the data buffer in
2411 * memory. Note that this is NOT A POINTER, but
2412 * the full 64bit physical address of the
2413 * buffer. This may be zero if buffer_length is
2415 * @param buffer_length
2416 * Length of buffer in bytes.
2417 * @param callback Function to call when this transaction
2418 * completes. If the return value of this
2419 * function isn't an error, then this function
2420 * is guaranteed to be called when the
2421 * transaction completes. If this parameter is
2422 * NULL, then the generic callback registered
2423 * through cvmx_usb_register_callback is
2424 * called. If both are NULL, then there is no
2425 * way to know when a transaction completes.
2426 * @param user_data User supplied data returned when the
2427 * callback is called. This is only used if
2428 * callback in not NULL.
2430 * @return A submitted transaction handle or negative on
2431 * failure. Negative values are failure codes from
2432 * cvmx_usb_status_t.
2434 int cvmx_usb_submit_interrupt(cvmx_usb_state_t *state, int pipe_handle,
2435 uint64_t buffer, int buffer_length,
2436 cvmx_usb_callback_func_t callback,
2440 cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
2442 CVMX_USB_LOG_CALLED();
2443 CVMX_USB_LOG_PARAM("%p", state);
2444 CVMX_USB_LOG_PARAM("%d", pipe_handle);
2445 CVMX_USB_LOG_PARAM("0x%llx", (unsigned long long)buffer);
2446 CVMX_USB_LOG_PARAM("%d", buffer_length);
2448 /* Pipe handle checking is done later in a common place */
2449 if (cvmx_unlikely(!buffer))
2450 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2451 if (cvmx_unlikely(buffer_length < 0))
2452 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2454 submit_handle = __cvmx_usb_submit_transaction(usb, pipe_handle,
2455 CVMX_USB_TRANSFER_INTERRUPT,
2459 0, /* control_header */
2460 0, /* iso_start_frame */
2461 0, /* iso_number_packets */
2462 NULL, /* iso_packets */
2465 CVMX_USB_RETURN(submit_handle);
2467 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
2468 EXPORT_SYMBOL(cvmx_usb_submit_interrupt);
2473 * Call to submit a USB Control transfer to a pipe.
2475 * @param state USB device state populated by
2476 * cvmx_usb_initialize().
2477 * @param pipe_handle
2478 * Handle to the pipe for the transfer.
2479 * @param control_header
2480 * USB 8 byte control header physical address.
2481 * Note that this is NOT A POINTER, but the
2482 * full 64bit physical address of the buffer.
2483 * @param buffer Physical address of the data buffer in
2484 * memory. Note that this is NOT A POINTER, but
2485 * the full 64bit physical address of the
2486 * buffer. This may be zero if buffer_length is
2488 * @param buffer_length
2489 * Length of buffer in bytes.
2490 * @param callback Function to call when this transaction
2491 * completes. If the return value of this
2492 * function isn't an error, then this function
2493 * is guaranteed to be called when the
2494 * transaction completes. If this parameter is
2495 * NULL, then the generic callback registered
2496 * through cvmx_usb_register_callback is
2497 * called. If both are NULL, then there is no
2498 * way to know when a transaction completes.
2499 * @param user_data User supplied data returned when the
2500 * callback is called. This is only used if
2501 * callback in not NULL.
2503 * @return A submitted transaction handle or negative on
2504 * failure. Negative values are failure codes from
2505 * cvmx_usb_status_t.
2507 int cvmx_usb_submit_control(cvmx_usb_state_t *state, int pipe_handle,
2508 uint64_t control_header,
2509 uint64_t buffer, int buffer_length,
2510 cvmx_usb_callback_func_t callback,
2514 cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
2515 cvmx_usb_control_header_t *header = cvmx_phys_to_ptr(control_header);
2517 CVMX_USB_LOG_CALLED();
2518 CVMX_USB_LOG_PARAM("%p", state);
2519 CVMX_USB_LOG_PARAM("%d", pipe_handle);
2520 CVMX_USB_LOG_PARAM("0x%llx", (unsigned long long)control_header);
2521 CVMX_USB_LOG_PARAM("0x%llx", (unsigned long long)buffer);
2522 CVMX_USB_LOG_PARAM("%d", buffer_length);
2524 /* Pipe handle checking is done later in a common place */
2525 if (cvmx_unlikely(!control_header))
2526 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2527 /* Some drivers send a buffer with a zero length. God only knows why */
2528 if (cvmx_unlikely(buffer && (buffer_length < 0)))
2529 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2530 if (cvmx_unlikely(!buffer && (buffer_length != 0)))
2531 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2532 if ((header->s.request_type & 0x80) == 0)
2533 buffer_length = cvmx_le16_to_cpu(header->s.length);
2535 submit_handle = __cvmx_usb_submit_transaction(usb, pipe_handle,
2536 CVMX_USB_TRANSFER_CONTROL,
2541 0, /* iso_start_frame */
2542 0, /* iso_number_packets */
2543 NULL, /* iso_packets */
2546 CVMX_USB_RETURN(submit_handle);
2548 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
2549 EXPORT_SYMBOL(cvmx_usb_submit_control);
2554 * Call to submit a USB Isochronous transfer to a pipe.
2556 * @param state USB device state populated by
2557 * cvmx_usb_initialize().
2558 * @param pipe_handle
2559 * Handle to the pipe for the transfer.
2560 * @param start_frame
2561 * Number of frames into the future to schedule
2563 * @param flags Flags to control the transfer. See
2564 * cvmx_usb_isochronous_flags_t for the flag
2566 * @param number_packets
2567 * Number of sequential packets to transfer.
2568 * "packets" is a pointer to an array of this
2569 * many packet structures.
2570 * @param packets Description of each transfer packet as
2571 * defined by cvmx_usb_iso_packet_t. The array
2572 * pointed to here must stay valid until the
2573 * complete callback is called.
2574 * @param buffer Physical address of the data buffer in
2575 * memory. Note that this is NOT A POINTER, but
2576 * the full 64bit physical address of the
2577 * buffer. This may be zero if buffer_length is
2579 * @param buffer_length
2580 * Length of buffer in bytes.
2581 * @param callback Function to call when this transaction
2582 * completes. If the return value of this
2583 * function isn't an error, then this function
2584 * is guaranteed to be called when the
2585 * transaction completes. If this parameter is
2586 * NULL, then the generic callback registered
2587 * through cvmx_usb_register_callback is
2588 * called. If both are NULL, then there is no
2589 * way to know when a transaction completes.
2590 * @param user_data User supplied data returned when the
2591 * callback is called. This is only used if
2592 * callback in not NULL.
2594 * @return A submitted transaction handle or negative on
2595 * failure. Negative values are failure codes from
2596 * cvmx_usb_status_t.
2598 int cvmx_usb_submit_isochronous(cvmx_usb_state_t *state, int pipe_handle,
2599 int start_frame, int flags,
2601 cvmx_usb_iso_packet_t packets[],
2602 uint64_t buffer, int buffer_length,
2603 cvmx_usb_callback_func_t callback,
2607 cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
2609 CVMX_USB_LOG_CALLED();
2610 CVMX_USB_LOG_PARAM("%p", state);
2611 CVMX_USB_LOG_PARAM("%d", pipe_handle);
2612 CVMX_USB_LOG_PARAM("%d", start_frame);
2613 CVMX_USB_LOG_PARAM("0x%x", flags);
2614 CVMX_USB_LOG_PARAM("%d", number_packets);
2615 CVMX_USB_LOG_PARAM("%p", packets);
2616 CVMX_USB_LOG_PARAM("0x%llx", (unsigned long long)buffer);
2617 CVMX_USB_LOG_PARAM("%d", buffer_length);
2619 /* Pipe handle checking is done later in a common place */
2620 if (cvmx_unlikely(start_frame < 0))
2621 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2622 if (cvmx_unlikely(flags & ~(CVMX_USB_ISOCHRONOUS_FLAGS_ALLOW_SHORT | CVMX_USB_ISOCHRONOUS_FLAGS_ASAP)))
2623 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2624 if (cvmx_unlikely(number_packets < 1))
2625 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2626 if (cvmx_unlikely(!packets))
2627 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2628 if (cvmx_unlikely(!buffer))
2629 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2630 if (cvmx_unlikely(buffer_length < 0))
2631 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2633 submit_handle = __cvmx_usb_submit_transaction(usb, pipe_handle,
2634 CVMX_USB_TRANSFER_ISOCHRONOUS,
2638 0, /* control_header */
2644 CVMX_USB_RETURN(submit_handle);
2646 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
2647 EXPORT_SYMBOL(cvmx_usb_submit_isochronous);
2652 * Cancel one outstanding request in a pipe. Canceling a request
2653 * can fail if the transaction has already completed before cancel
2654 * is called. Even after a successful cancel call, it may take
2655 * a frame or two for the cvmx_usb_poll() function to call the
2656 * associated callback.
2658 * @param state USB device state populated by
2659 * cvmx_usb_initialize().
2660 * @param pipe_handle
2661 * Pipe handle to cancel requests in.
2662 * @param submit_handle
2663 * Handle to transaction to cancel, returned by the submit function.
2665 * @return CVMX_USB_SUCCESS or a negative error code defined in
2666 * cvmx_usb_status_t.
2668 cvmx_usb_status_t cvmx_usb_cancel(cvmx_usb_state_t *state, int pipe_handle,
2671 cvmx_usb_transaction_t *transaction;
2672 cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
2673 cvmx_usb_pipe_t *pipe = usb->pipe + pipe_handle;
2675 CVMX_USB_LOG_CALLED();
2676 CVMX_USB_LOG_PARAM("%p", state);
2677 CVMX_USB_LOG_PARAM("%d", pipe_handle);
2678 CVMX_USB_LOG_PARAM("%d", submit_handle);
2680 if (cvmx_unlikely((pipe_handle < 0) || (pipe_handle >= MAX_PIPES)))
2681 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2682 if (cvmx_unlikely((submit_handle < 0) || (submit_handle >= MAX_TRANSACTIONS)))
2683 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2685 /* Fail if the pipe isn't open */
2686 if (cvmx_unlikely((pipe->flags & __CVMX_USB_PIPE_FLAGS_OPEN) == 0))
2687 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2689 transaction = usb->transaction + submit_handle;
2691 /* Fail if this transaction already completed */
2692 if (cvmx_unlikely((transaction->flags & __CVMX_USB_TRANSACTION_FLAGS_IN_USE) == 0))
2693 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2695 /* If the transaction is the HEAD of the queue and scheduled. We need to
2697 if ((pipe->head == transaction) &&
2698 (pipe->flags & __CVMX_USB_PIPE_FLAGS_SCHEDULED))
2700 cvmx_usbcx_hccharx_t usbc_hcchar;
2702 usb->pipe_for_channel[pipe->channel] = NULL;
2703 pipe->flags &= ~__CVMX_USB_PIPE_FLAGS_SCHEDULED;
2707 usbc_hcchar.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCCHARX(pipe->channel, usb->index));
2708 /* If the channel isn't enabled then the transaction already completed */
2709 if (usbc_hcchar.s.chena)
2711 usbc_hcchar.s.chdis = 1;
2712 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCCHARX(pipe->channel, usb->index), usbc_hcchar.u32);
2715 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_CANCEL);
2716 CVMX_USB_RETURN(CVMX_USB_SUCCESS);
2718 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
2719 EXPORT_SYMBOL(cvmx_usb_cancel);
2724 * Cancel all outstanding requests in a pipe. Logically all this
2725 * does is call cvmx_usb_cancel() in a loop.
2727 * @param state USB device state populated by
2728 * cvmx_usb_initialize().
2729 * @param pipe_handle
2730 * Pipe handle to cancel requests in.
2732 * @return CVMX_USB_SUCCESS or a negative error code defined in
2733 * cvmx_usb_status_t.
2735 cvmx_usb_status_t cvmx_usb_cancel_all(cvmx_usb_state_t *state, int pipe_handle)
2737 cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
2738 cvmx_usb_pipe_t *pipe = usb->pipe + pipe_handle;
2740 CVMX_USB_LOG_CALLED();
2741 CVMX_USB_LOG_PARAM("%p", state);
2742 CVMX_USB_LOG_PARAM("%d", pipe_handle);
2743 if (cvmx_unlikely((pipe_handle < 0) || (pipe_handle >= MAX_PIPES)))
2744 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2746 /* Fail if the pipe isn't open */
2747 if (cvmx_unlikely((pipe->flags & __CVMX_USB_PIPE_FLAGS_OPEN) == 0))
2748 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2750 /* Simply loop through and attempt to cancel each transaction */
2753 cvmx_usb_status_t result = cvmx_usb_cancel(state, pipe_handle,
2754 __cvmx_usb_get_submit_handle(usb, pipe->head));
2755 if (cvmx_unlikely(result != CVMX_USB_SUCCESS))
2756 CVMX_USB_RETURN(result);
2758 CVMX_USB_RETURN(CVMX_USB_SUCCESS);
2760 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
2761 EXPORT_SYMBOL(cvmx_usb_cancel_all);
2766 * Close a pipe created with cvmx_usb_open_pipe().
2768 * @param state USB device state populated by
2769 * cvmx_usb_initialize().
2770 * @param pipe_handle
2771 * Pipe handle to close.
2773 * @return CVMX_USB_SUCCESS or a negative error code defined in
2774 * cvmx_usb_status_t. CVMX_USB_BUSY is returned if the
2775 * pipe has outstanding transfers.
2777 cvmx_usb_status_t cvmx_usb_close_pipe(cvmx_usb_state_t *state, int pipe_handle)
2779 cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
2780 cvmx_usb_pipe_t *pipe = usb->pipe + pipe_handle;
2782 CVMX_USB_LOG_CALLED();
2783 CVMX_USB_LOG_PARAM("%p", state);
2784 CVMX_USB_LOG_PARAM("%d", pipe_handle);
2785 if (cvmx_unlikely((pipe_handle < 0) || (pipe_handle >= MAX_PIPES)))
2786 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2788 /* Fail if the pipe isn't open */
2789 if (cvmx_unlikely((pipe->flags & __CVMX_USB_PIPE_FLAGS_OPEN) == 0))
2790 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2792 /* Fail if the pipe has pending transactions */
2793 if (cvmx_unlikely(pipe->head))
2794 CVMX_USB_RETURN(CVMX_USB_BUSY);
2797 __cvmx_usb_remove_pipe(&usb->idle_pipes, pipe);
2798 __cvmx_usb_append_pipe(&usb->free_pipes, pipe);
2800 CVMX_USB_RETURN(CVMX_USB_SUCCESS);
2802 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
2803 EXPORT_SYMBOL(cvmx_usb_close_pipe);
2808 * Register a function to be called when various USB events occur.
2810 * @param state USB device state populated by
2811 * cvmx_usb_initialize().
2812 * @param reason Which event to register for.
2813 * @param callback Function to call when the event occurs.
2814 * @param user_data User data parameter to the function.
2816 * @return CVMX_USB_SUCCESS or a negative error code defined in
2817 * cvmx_usb_status_t.
2819 cvmx_usb_status_t cvmx_usb_register_callback(cvmx_usb_state_t *state,
2820 cvmx_usb_callback_t reason,
2821 cvmx_usb_callback_func_t callback,
2824 cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
2826 CVMX_USB_LOG_CALLED();
2827 CVMX_USB_LOG_PARAM("%p", state);
2828 CVMX_USB_LOG_PARAM("%d", reason);
2829 CVMX_USB_LOG_PARAM("%p", callback);
2830 CVMX_USB_LOG_PARAM("%p", user_data);
2831 if (cvmx_unlikely(reason >= __CVMX_USB_CALLBACK_END))
2832 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2833 if (cvmx_unlikely(!callback))
2834 CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM);
2836 usb->callback[reason] = callback;
2837 usb->callback_data[reason] = user_data;
2839 CVMX_USB_RETURN(CVMX_USB_SUCCESS);
2841 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
2842 EXPORT_SYMBOL(cvmx_usb_register_callback);
2847 * Get the current USB protocol level frame number. The frame
2848 * number is always in the range of 0-0x7ff.
2850 * @param state USB device state populated by
2851 * cvmx_usb_initialize().
2853 * @return USB frame number
2855 int cvmx_usb_get_frame_number(cvmx_usb_state_t *state)
2858 cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
2859 cvmx_usbcx_hfnum_t usbc_hfnum;
2861 CVMX_USB_LOG_CALLED();
2862 CVMX_USB_LOG_PARAM("%p", state);
2864 usbc_hfnum.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index));
2865 frame_number = usbc_hfnum.s.frnum;
2867 CVMX_USB_RETURN(frame_number);
2869 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
2870 EXPORT_SYMBOL(cvmx_usb_get_frame_number);
2876 * Poll a channel for status
2878 * @param usb USB device
2879 * @param channel Channel to poll
2881 * @return Zero on success
2883 static int __cvmx_usb_poll_channel(cvmx_usb_internal_state_t *usb, int channel)
2885 cvmx_usbcx_hcintx_t usbc_hcint;
2886 cvmx_usbcx_hctsizx_t usbc_hctsiz;
2887 cvmx_usbcx_hccharx_t usbc_hcchar;
2888 cvmx_usb_pipe_t *pipe;
2889 cvmx_usb_transaction_t *transaction;
2890 int bytes_this_transfer;
2891 int bytes_in_last_packet;
2892 int packets_processed;
2893 int buffer_space_left;
2894 CVMX_USB_LOG_CALLED();
2895 CVMX_USB_LOG_PARAM("%p", usb);
2896 CVMX_USB_LOG_PARAM("%d", channel);
2898 /* Read the interrupt status bits for the channel */
2899 usbc_hcint.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCINTX(channel, usb->index));
2902 cvmx_dprintf("Channel %d%s%s%s%s%s%s%s%s%s%s%s\n", channel,
2903 (usbc_hcint.s.datatglerr) ? " DATATGLERR" : "",
2904 (usbc_hcint.s.frmovrun) ? " FRMOVRUN" : "",
2905 (usbc_hcint.s.bblerr) ? " BBLERR" : "",
2906 (usbc_hcint.s.xacterr) ? " XACTERR" : "",
2907 (usbc_hcint.s.nyet) ? " NYET" : "",
2908 (usbc_hcint.s.ack) ? " ACK" : "",
2909 (usbc_hcint.s.nak) ? " NAK" : "",
2910 (usbc_hcint.s.stall) ? " STALL" : "",
2911 (usbc_hcint.s.ahberr) ? " AHBERR" : "",
2912 (usbc_hcint.s.chhltd) ? " CHHLTD" : "",
2913 (usbc_hcint.s.xfercompl) ? " XFERCOMPL" : "");
2916 if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
2918 usbc_hcchar.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index));
2920 if (usbc_hcchar.s.chena && usbc_hcchar.s.chdis)
2922 /* There seems to be a bug in CN31XX which can cause interrupt
2923 IN transfers to get stuck until we do a write of HCCHARX
2924 without changing things */
2925 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index), usbc_hcchar.u32);
2929 /* In non DMA mode the channels don't halt themselves. We need to
2930 manually disable channels that are left running */
2931 if (!usbc_hcint.s.chhltd)
2933 if (usbc_hcchar.s.chena)
2935 cvmx_usbcx_hcintmskx_t hcintmsk;
2936 /* Disable all interrupts except CHHLTD */
2938 hcintmsk.s.chhltdmsk = 1;
2939 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), hcintmsk.u32);
2940 usbc_hcchar.s.chdis = 1;
2941 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index), usbc_hcchar.u32);
2944 else if (usbc_hcint.s.xfercompl)
2946 /* Successful IN/OUT with transfer complete. Channel halt isn't needed */
2950 cvmx_dprintf("USB%d: Channel %d interrupt without halt\n", usb->index, channel);
2957 /* There is are no interrupts that we need to process when the channel is
2959 if (!usbc_hcint.s.chhltd)
2963 /* Disable the channel interrupts now that it is done */
2964 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), 0);
2965 usb->idle_hardware_channels |= (1<<channel);
2967 /* Make sure this channel is tied to a valid pipe */
2968 pipe = usb->pipe_for_channel[channel];
2969 CVMX_PREFETCH(pipe, 0);
2970 CVMX_PREFETCH(pipe, 128);
2973 transaction = pipe->head;
2974 CVMX_PREFETCH0(transaction);
2976 /* Disconnect this pipe from the HW channel. Later the schedule function will
2977 figure out which pipe needs to go */
2978 usb->pipe_for_channel[channel] = NULL;
2979 pipe->flags &= ~__CVMX_USB_PIPE_FLAGS_SCHEDULED;
2981 /* Read the channel config info so we can figure out how much data
2983 usbc_hcchar.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index));
2984 usbc_hctsiz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index));
2986 /* Calculating the number of bytes successfully transferred is dependent on
2987 the transfer direction */
2988 packets_processed = transaction->pktcnt - usbc_hctsiz.s.pktcnt;
2989 if (usbc_hcchar.s.epdir)
2991 /* IN transactions are easy. For every byte received the hardware
2992 decrements xfersize. All we need to do is subtract the current
2993 value of xfersize from its starting value and we know how many
2994 bytes were written to the buffer */
2995 bytes_this_transfer = transaction->xfersize - usbc_hctsiz.s.xfersize;
2999 /* OUT transaction don't decrement xfersize. Instead pktcnt is
3000 decremented on every successful packet send. The hardware does
3001 this when it receives an ACK, or NYET. If it doesn't
3002 receive one of these responses pktcnt doesn't change */
3003 bytes_this_transfer = packets_processed * usbc_hcchar.s.mps;
3004 /* The last packet may not be a full transfer if we didn't have
3006 if (bytes_this_transfer > transaction->xfersize)
3007 bytes_this_transfer = transaction->xfersize;
3009 /* Figure out how many bytes were in the last packet of the transfer */
3010 if (packets_processed)
3011 bytes_in_last_packet = bytes_this_transfer - (packets_processed-1) * usbc_hcchar.s.mps;
3013 bytes_in_last_packet = bytes_this_transfer;
3015 /* As a special case, setup transactions output the setup header, not
3016 the user's data. For this reason we don't count setup data as bytes
3018 if ((transaction->stage == CVMX_USB_STAGE_SETUP) ||
3019 (transaction->stage == CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE))
3020 bytes_this_transfer = 0;
3022 /* Optional debug output */
3023 if (cvmx_unlikely((usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_TRANSFERS) ||
3024 (pipe->flags & CVMX_USB_PIPE_FLAGS_DEBUG_TRANSFERS)))
3025 cvmx_dprintf("%s: Channel %d halted. Pipe %d transaction %d stage %d bytes=%d\n",
3026 __FUNCTION__, channel,
3027 __cvmx_usb_get_pipe_handle(usb, pipe),
3028 __cvmx_usb_get_submit_handle(usb, transaction),
3029 transaction->stage, bytes_this_transfer);
3031 /* Add the bytes transferred to the running total. It is important that
3032 bytes_this_transfer doesn't count any data that needs to be
3034 transaction->actual_bytes += bytes_this_transfer;
3035 if (transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS)
3036 buffer_space_left = transaction->iso_packets[0].length - transaction->actual_bytes;
3038 buffer_space_left = transaction->buffer_length - transaction->actual_bytes;
3040 /* We need to remember the PID toggle state for the next transaction. The
3041 hardware already updated it for the next transaction */
3042 pipe->pid_toggle = !(usbc_hctsiz.s.pid == 0);
3044 /* For high speed bulk out, assume the next transaction will need to do a
3045 ping before proceeding. If this isn't true the ACK processing below
3046 will clear this flag */
3047 if ((pipe->device_speed == CVMX_USB_SPEED_HIGH) &&
3048 (pipe->transfer_type == CVMX_USB_TRANSFER_BULK) &&
3049 (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT))
3050 pipe->flags |= __CVMX_USB_PIPE_FLAGS_NEED_PING;
3052 if (usbc_hcint.s.stall)
3054 /* STALL as a response means this transaction cannot be completed
3055 because the device can't process transactions. Tell the user. Any
3056 data that was transferred will be counted on the actual bytes
3058 pipe->pid_toggle = 0;
3059 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_STALL);
3061 else if (usbc_hcint.s.xacterr)
3063 /* We know at least one packet worked if we get a ACK or NAK. Reset the retry counter */
3064 if (usbc_hcint.s.nak || usbc_hcint.s.ack)
3065 transaction->retries = 0;
3066 transaction->retries++;
3067 if (transaction->retries > MAX_RETRIES)
3069 /* XactErr as a response means the device signaled something wrong with
3070 the transfer. For example, PID toggle errors cause these */
3071 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_XACTERR);
3075 /* If this was a split then clear our split in progress marker */
3076 if (usb->active_split == transaction)
3077 usb->active_split = NULL;
3078 /* Rewind to the beginning of the transaction by anding off the
3079 split complete bit */
3080 transaction->stage &= ~1;
3081 pipe->split_sc_frame = -1;
3082 pipe->next_tx_frame += pipe->interval;
3083 if (pipe->next_tx_frame < usb->frame_number)
3084 pipe->next_tx_frame = usb->frame_number + pipe->interval -
3085 (usb->frame_number - pipe->next_tx_frame) % pipe->interval;
3088 else if (usbc_hcint.s.bblerr)
3090 /* Babble Error (BblErr) */
3091 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_BABBLEERR);
3093 else if (usbc_hcint.s.datatglerr)
3095 /* We'll retry the exact same transaction again */
3096 transaction->retries++;
3098 else if (usbc_hcint.s.nyet)
3100 /* NYET as a response is only allowed in three cases: as a response to
3101 a ping, as a response to a split transaction, and as a response to
3102 a bulk out. The ping case is handled by hardware, so we only have
3103 splits and bulk out */
3104 if (!__cvmx_usb_pipe_needs_split(usb, pipe))
3106 transaction->retries = 0;
3107 /* If there is more data to go then we need to try again. Otherwise
3108 this transaction is complete */
3109 if ((buffer_space_left == 0) || (bytes_in_last_packet < pipe->max_packet))
3110 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
3114 /* Split transactions retry the split complete 4 times then rewind
3115 to the start split and do the entire transactions again */
3116 transaction->retries++;
3117 if ((transaction->retries & 0x3) == 0)
3119 /* Rewind to the beginning of the transaction by anding off the
3120 split complete bit */
3121 transaction->stage &= ~1;
3122 pipe->split_sc_frame = -1;
3126 else if (usbc_hcint.s.ack)
3128 transaction->retries = 0;
3129 /* The ACK bit can only be checked after the other error bits. This is
3130 because a multi packet transfer may succeed in a number of packets
3131 and then get a different response on the last packet. In this case
3132 both ACK and the last response bit will be set. If none of the
3133 other response bits is set, then the last packet must have been an
3136 /* Since we got an ACK, we know we don't need to do a ping on this
3138 pipe->flags &= ~__CVMX_USB_PIPE_FLAGS_NEED_PING;
3140 switch (transaction->type)
3142 case CVMX_USB_TRANSFER_CONTROL:
3143 switch (transaction->stage)
3145 case CVMX_USB_STAGE_NON_CONTROL:
3146 case CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE:
3147 /* This should be impossible */
3148 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_ERROR);
3150 case CVMX_USB_STAGE_SETUP:
3151 pipe->pid_toggle = 1;
3152 if (__cvmx_usb_pipe_needs_split(usb, pipe))
3153 transaction->stage = CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE;
3156 cvmx_usb_control_header_t *header = cvmx_phys_to_ptr(transaction->control_header);
3157 if (header->s.length)
3158 transaction->stage = CVMX_USB_STAGE_DATA;
3160 transaction->stage = CVMX_USB_STAGE_STATUS;
3163 case CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE:
3165 cvmx_usb_control_header_t *header = cvmx_phys_to_ptr(transaction->control_header);
3166 if (header->s.length)
3167 transaction->stage = CVMX_USB_STAGE_DATA;
3169 transaction->stage = CVMX_USB_STAGE_STATUS;
3172 case CVMX_USB_STAGE_DATA:
3173 if (__cvmx_usb_pipe_needs_split(usb, pipe))
3175 transaction->stage = CVMX_USB_STAGE_DATA_SPLIT_COMPLETE;
3176 /* For setup OUT data that are splits, the hardware
3177 doesn't appear to count transferred data. Here
3178 we manually update the data transferred */
3179 if (!usbc_hcchar.s.epdir)
3181 if (buffer_space_left < pipe->max_packet)
3182 transaction->actual_bytes += buffer_space_left;
3184 transaction->actual_bytes += pipe->max_packet;
3187 else if ((buffer_space_left == 0) || (bytes_in_last_packet < pipe->max_packet))
3189 pipe->pid_toggle = 1;
3190 transaction->stage = CVMX_USB_STAGE_STATUS;
3193 case CVMX_USB_STAGE_DATA_SPLIT_COMPLETE:
3194 if ((buffer_space_left == 0) || (bytes_in_last_packet < pipe->max_packet))
3196 pipe->pid_toggle = 1;
3197 transaction->stage = CVMX_USB_STAGE_STATUS;
3201 transaction->stage = CVMX_USB_STAGE_DATA;
3204 case CVMX_USB_STAGE_STATUS:
3205 if (__cvmx_usb_pipe_needs_split(usb, pipe))
3206 transaction->stage = CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE;
3208 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
3210 case CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE:
3211 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
3215 case CVMX_USB_TRANSFER_BULK:
3216 case CVMX_USB_TRANSFER_INTERRUPT:
3217 /* The only time a bulk transfer isn't complete when
3218 it finishes with an ACK is during a split transaction. For
3219 splits we need to continue the transfer if more data is
3221 if (__cvmx_usb_pipe_needs_split(usb, pipe))
3223 if (transaction->stage == CVMX_USB_STAGE_NON_CONTROL)
3224 transaction->stage = CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE;
3227 if (buffer_space_left && (bytes_in_last_packet == pipe->max_packet))
3228 transaction->stage = CVMX_USB_STAGE_NON_CONTROL;
3231 if (transaction->type == CVMX_USB_TRANSFER_INTERRUPT)
3232 pipe->next_tx_frame += pipe->interval;
3233 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
3239 if ((pipe->device_speed == CVMX_USB_SPEED_HIGH) &&
3240 (pipe->transfer_type == CVMX_USB_TRANSFER_BULK) &&
3241 (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) &&
3243 pipe->flags |= __CVMX_USB_PIPE_FLAGS_NEED_PING;
3244 if (!buffer_space_left || (bytes_in_last_packet < pipe->max_packet))
3246 if (transaction->type == CVMX_USB_TRANSFER_INTERRUPT)
3247 pipe->next_tx_frame += pipe->interval;
3248 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
3252 case CVMX_USB_TRANSFER_ISOCHRONOUS:
3253 if (__cvmx_usb_pipe_needs_split(usb, pipe))
3255 /* ISOCHRONOUS OUT splits don't require a complete split stage.
3256 Instead they use a sequence of begin OUT splits to transfer
3257 the data 188 bytes at a time. Once the transfer is complete,
3258 the pipe sleeps until the next schedule interval */
3259 if (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT)
3261 /* If no space left or this wasn't a max size packet then
3262 this transfer is complete. Otherwise start it again
3263 to send the next 188 bytes */
3264 if (!buffer_space_left || (bytes_this_transfer < 188))
3266 pipe->next_tx_frame += pipe->interval;
3267 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
3272 if (transaction->stage == CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE)
3274 /* We are in the incoming data phase. Keep getting
3275 data until we run out of space or get a small
3277 if ((buffer_space_left == 0) || (bytes_in_last_packet < pipe->max_packet))
3279 pipe->next_tx_frame += pipe->interval;
3280 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
3284 transaction->stage = CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE;
3289 pipe->next_tx_frame += pipe->interval;
3290 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
3295 else if (usbc_hcint.s.nak)
3297 /* If this was a split then clear our split in progress marker */
3298 if (usb->active_split == transaction)
3299 usb->active_split = NULL;
3300 /* NAK as a response means the device couldn't accept the transaction,
3301 but it should be retried in the future. Rewind to the beginning of
3302 the transaction by anding off the split complete bit. Retry in the
3304 transaction->retries = 0;
3305 transaction->stage &= ~1;
3306 pipe->next_tx_frame += pipe->interval;
3307 if (pipe->next_tx_frame < usb->frame_number)
3308 pipe->next_tx_frame = usb->frame_number + pipe->interval -
3309 (usb->frame_number - pipe->next_tx_frame) % pipe->interval;
3313 cvmx_usb_port_status_t port;
3314 port = cvmx_usb_get_status((cvmx_usb_state_t *)usb);
3315 if (port.port_enabled)
3317 /* We'll retry the exact same transaction again */
3318 transaction->retries++;
3322 /* We get channel halted interrupts with no result bits sets when the
3323 cable is unplugged */
3324 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_ERROR);
3332 * Poll the USB block for status and call all needed callback
3333 * handlers. This function is meant to be called in the interrupt
3334 * handler for the USB controller. It can also be called
3335 * periodically in a loop for non-interrupt based operation.
3337 * @param state USB device state populated by
3338 * cvmx_usb_initialize().
3340 * @return CVMX_USB_SUCCESS or a negative error code defined in
3341 * cvmx_usb_status_t.
3343 cvmx_usb_status_t cvmx_usb_poll(cvmx_usb_state_t *state)
3345 cvmx_usbcx_hfnum_t usbc_hfnum;
3346 cvmx_usbcx_gintsts_t usbc_gintsts;
3347 cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
3349 CVMX_PREFETCH(usb, 0);
3350 CVMX_PREFETCH(usb, 1*128);
3351 CVMX_PREFETCH(usb, 2*128);
3352 CVMX_PREFETCH(usb, 3*128);
3353 CVMX_PREFETCH(usb, 4*128);
3355 CVMX_USB_LOG_CALLED();
3356 CVMX_USB_LOG_PARAM("%p", state);
3358 /* Update the frame counter */
3359 usbc_hfnum.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index));
3360 if ((usb->frame_number&0x3fff) > usbc_hfnum.s.frnum)
3361 usb->frame_number += 0x4000;
3362 usb->frame_number &= ~0x3fffull;
3363 usb->frame_number |= usbc_hfnum.s.frnum;
3365 /* Read the pending interrupts */
3366 usbc_gintsts.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GINTSTS(usb->index));
3368 /* Clear the interrupts now that we know about them */
3369 __cvmx_usb_write_csr32(usb, CVMX_USBCX_GINTSTS(usb->index), usbc_gintsts.u32);
3371 if (usbc_gintsts.s.rxflvl)
3373 /* RxFIFO Non-Empty (RxFLvl)
3374 Indicates that there is at least one packet pending to be read
3376 /* In DMA mode this is handled by hardware */
3377 if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
3378 __cvmx_usb_poll_rx_fifo(usb);
3380 if (usbc_gintsts.s.ptxfemp || usbc_gintsts.s.nptxfemp)
3382 /* Fill the Tx FIFOs when not in DMA mode */
3383 if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
3384 __cvmx_usb_poll_tx_fifo(usb);
3386 if (usbc_gintsts.s.disconnint || usbc_gintsts.s.prtint)
3388 cvmx_usbcx_hprt_t usbc_hprt;
3389 /* Disconnect Detected Interrupt (DisconnInt)
3390 Asserted when a device disconnect is detected. */
3392 /* Host Port Interrupt (PrtInt)
3393 The core sets this bit to indicate a change in port status of one
3394 of the O2P USB core ports in Host mode. The application must
3395 read the Host Port Control and Status (HPRT) register to
3396 determine the exact event that caused this interrupt. The
3397 application must clear the appropriate status bit in the Host Port
3398 Control and Status register to clear this bit. */
3400 /* Call the user's port callback */
3401 __cvmx_usb_perform_callback(usb, NULL, NULL,
3402 CVMX_USB_CALLBACK_PORT_CHANGED,
3403 CVMX_USB_COMPLETE_SUCCESS);
3404 /* Clear the port change bits */
3405 usbc_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
3406 usbc_hprt.s.prtena = 0;
3407 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HPRT(usb->index), usbc_hprt.u32);
3409 if (usbc_gintsts.s.hchint)
3411 /* Host Channels Interrupt (HChInt)
3412 The core sets this bit to indicate that an interrupt is pending on
3413 one of the channels of the core (in Host mode). The application
3414 must read the Host All Channels Interrupt (HAINT) register to
3415 determine the exact number of the channel on which the
3416 interrupt occurred, and then read the corresponding Host
3417 Channel-n Interrupt (HCINTn) register to determine the exact
3418 cause of the interrupt. The application must clear the
3419 appropriate status bit in the HCINTn register to clear this bit. */
3420 cvmx_usbcx_haint_t usbc_haint;
3421 usbc_haint.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HAINT(usb->index));
3422 while (usbc_haint.u32)
3425 CVMX_CLZ(channel, usbc_haint.u32);
3426 channel = 31 - channel;
3427 __cvmx_usb_poll_channel(usb, channel);
3428 usbc_haint.u32 ^= 1<<channel;
3432 __cvmx_usb_schedule(usb, usbc_gintsts.s.sof);
3434 CVMX_USB_RETURN(CVMX_USB_SUCCESS);
3436 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
3437 EXPORT_SYMBOL(cvmx_usb_poll);
3440 extern void cvmx_usb_set_toggle(cvmx_usb_state_t *state, int endpoint_num, int toggle)
3442 cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
3443 cvmx_usb_pipe_t *pipe = usb->pipe + endpoint_num;
3445 pipe->pid_toggle = !!toggle;
3448 extern int cvmx_usb_get_toggle(cvmx_usb_state_t *state, int endpoint_num)
3450 cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state;
3451 cvmx_usb_pipe_t *pipe = usb->pipe + endpoint_num;
3453 if (pipe->pid_toggle)