diff options
-rw-r--r-- | drivers/staging/Kconfig | 2 | ||||
-rw-r--r-- | drivers/staging/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/octeon-usb/Kconfig | 10 | ||||
-rw-r--r-- | drivers/staging/octeon-usb/Makefile | 3 | ||||
-rw-r--r-- | drivers/staging/octeon-usb/TODO | 11 | ||||
-rw-r--r-- | drivers/staging/octeon-usb/cvmx-usb.c | 3344 | ||||
-rw-r--r-- | drivers/staging/octeon-usb/cvmx-usb.h | 1085 | ||||
-rw-r--r-- | drivers/staging/octeon-usb/cvmx-usbcx-defs.h | 3086 | ||||
-rw-r--r-- | drivers/staging/octeon-usb/cvmx-usbnx-defs.h | 1596 | ||||
-rw-r--r-- | drivers/staging/octeon-usb/octeon-hcd.c | 854 |
10 files changed, 9992 insertions, 0 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 4464f2603889..f64b662c74db 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig | |||
@@ -62,6 +62,8 @@ source "drivers/staging/line6/Kconfig" | |||
62 | 62 | ||
63 | source "drivers/staging/octeon/Kconfig" | 63 | source "drivers/staging/octeon/Kconfig" |
64 | 64 | ||
65 | source "drivers/staging/octeon-usb/Kconfig" | ||
66 | |||
65 | source "drivers/staging/serqt_usb2/Kconfig" | 67 | source "drivers/staging/serqt_usb2/Kconfig" |
66 | 68 | ||
67 | source "drivers/staging/vt6655/Kconfig" | 69 | source "drivers/staging/vt6655/Kconfig" |
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index f689b9d1352d..1fb58a1562cb 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile | |||
@@ -25,6 +25,7 @@ obj-$(CONFIG_LINE6_USB) += line6/ | |||
25 | obj-$(CONFIG_NETLOGIC_XLR_NET) += netlogic/ | 25 | obj-$(CONFIG_NETLOGIC_XLR_NET) += netlogic/ |
26 | obj-$(CONFIG_USB_SERIAL_QUATECH2) += serqt_usb2/ | 26 | obj-$(CONFIG_USB_SERIAL_QUATECH2) += serqt_usb2/ |
27 | obj-$(CONFIG_OCTEON_ETHERNET) += octeon/ | 27 | obj-$(CONFIG_OCTEON_ETHERNET) += octeon/ |
28 | obj-$(CONFIG_OCTEON_USB) += octeon-usb/ | ||
28 | obj-$(CONFIG_VT6655) += vt6655/ | 29 | obj-$(CONFIG_VT6655) += vt6655/ |
29 | obj-$(CONFIG_VT6656) += vt6656/ | 30 | obj-$(CONFIG_VT6656) += vt6656/ |
30 | obj-$(CONFIG_VME_BUS) += vme/ | 31 | obj-$(CONFIG_VME_BUS) += vme/ |
diff --git a/drivers/staging/octeon-usb/Kconfig b/drivers/staging/octeon-usb/Kconfig new file mode 100644 index 000000000000..018af6db08c8 --- /dev/null +++ b/drivers/staging/octeon-usb/Kconfig | |||
@@ -0,0 +1,10 @@ | |||
1 | config OCTEON_USB | ||
2 | tristate "Cavium Networks Octeon USB support" | ||
3 | depends on CPU_CAVIUM_OCTEON && USB | ||
4 | help | ||
5 | This driver supports USB host controller on some Cavium | ||
6 | Networks' products in the Octeon family. | ||
7 | |||
8 | To compile this driver as a module, choose M here. The module | ||
9 | will be called octeon-usb. | ||
10 | |||
diff --git a/drivers/staging/octeon-usb/Makefile b/drivers/staging/octeon-usb/Makefile new file mode 100644 index 000000000000..89df1ad8be30 --- /dev/null +++ b/drivers/staging/octeon-usb/Makefile | |||
@@ -0,0 +1,3 @@ | |||
1 | obj-${CONFIG_OCTEON_USB} := octeon-usb.o | ||
2 | octeon-usb-y := octeon-hcd.o | ||
3 | octeon-usb-y += cvmx-usb.o | ||
diff --git a/drivers/staging/octeon-usb/TODO b/drivers/staging/octeon-usb/TODO new file mode 100644 index 000000000000..cc58a7e88baf --- /dev/null +++ b/drivers/staging/octeon-usb/TODO | |||
@@ -0,0 +1,11 @@ | |||
1 | This driver is functional and has been tested on EdgeRouter Lite with | ||
2 | USB mass storage. | ||
3 | |||
4 | TODO: | ||
5 | - kernel coding style | ||
6 | - checkpatch warnings | ||
7 | - dead code elimination | ||
8 | - device tree bindings | ||
9 | - possibly eliminate the extra "hardware abstraction layer" | ||
10 | |||
11 | Contact: Aaro Koskinen <aaro.koskinen@iki.fi> | ||
diff --git a/drivers/staging/octeon-usb/cvmx-usb.c b/drivers/staging/octeon-usb/cvmx-usb.c new file mode 100644 index 000000000000..08ee4ab46c8a --- /dev/null +++ b/drivers/staging/octeon-usb/cvmx-usb.c | |||
@@ -0,0 +1,3344 @@ | |||
1 | /***********************license start*************** | ||
2 | * Copyright (c) 2003-2010 Cavium Networks (support@cavium.com). All rights | ||
3 | * reserved. | ||
4 | * | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions are | ||
8 | * met: | ||
9 | * | ||
10 | * * Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * | ||
13 | * * Redistributions in binary form must reproduce the above | ||
14 | * copyright notice, this list of conditions and the following | ||
15 | * disclaimer in the documentation and/or other materials provided | ||
16 | * with the distribution. | ||
17 | |||
18 | * * Neither the name of Cavium Networks nor the names of | ||
19 | * its contributors may be used to endorse or promote products | ||
20 | * derived from this software without specific prior written | ||
21 | * permission. | ||
22 | |||
23 | * This Software, including technical data, may be subject to U.S. export control | ||
24 | * laws, including the U.S. Export Administration Act and its associated | ||
25 | * regulations, and may be subject to export or import regulations in other | ||
26 | * countries. | ||
27 | |||
28 | * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" | ||
29 | * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR | ||
30 | * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO | ||
31 | * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR | ||
32 | * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM | ||
33 | * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, | ||
34 | * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF | ||
35 | * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR | ||
36 | * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR | ||
37 | * PERFORMANCE OF THE SOFTWARE LIES WITH YOU. | ||
38 | ***********************license end**************************************/ | ||
39 | |||
40 | |||
41 | /** | ||
42 | * @file | ||
43 | * | ||
44 | * "cvmx-usb.c" defines a set of low level USB functions to help | ||
45 | * developers create Octeon USB drivers for various operating | ||
46 | * systems. These functions provide a generic API to the Octeon | ||
47 | * USB blocks, hiding the internal hardware specific | ||
48 | * operations. | ||
49 | * | ||
50 | * <hr>$Revision: 32636 $<hr> | ||
51 | */ | ||
52 | #include <linux/delay.h> | ||
53 | #include <asm/octeon/cvmx.h> | ||
54 | #include <asm/octeon/octeon.h> | ||
55 | #include <asm/octeon/cvmx-sysinfo.h> | ||
56 | #include "cvmx-usbnx-defs.h" | ||
57 | #include "cvmx-usbcx-defs.h" | ||
58 | #include "cvmx-usb.h" | ||
59 | #include <asm/octeon/cvmx-helper.h> | ||
60 | #include <asm/octeon/cvmx-helper-board.h> | ||
61 | |||
62 | #define CVMX_PREFETCH0(address) CVMX_PREFETCH(address, 0) | ||
63 | #define CVMX_PREFETCH128(address) CVMX_PREFETCH(address, 128) | ||
64 | // a normal prefetch | ||
65 | #define CVMX_PREFETCH(address, offset) CVMX_PREFETCH_PREF0(address, offset) | ||
66 | // normal prefetches that use the pref instruction | ||
67 | #define CVMX_PREFETCH_PREFX(X, address, offset) asm volatile ("pref %[type], %[off](%[rbase])" : : [rbase] "d" (address), [off] "I" (offset), [type] "n" (X)) | ||
68 | #define CVMX_PREFETCH_PREF0(address, offset) CVMX_PREFETCH_PREFX(0, address, offset) | ||
69 | #define CVMX_CLZ(result, input) asm ("clz %[rd],%[rs]" : [rd] "=d" (result) : [rs] "d" (input)) | ||
70 | |||
71 | #define cvmx_likely likely | ||
72 | #define cvmx_wait_usec udelay | ||
73 | #define cvmx_unlikely unlikely | ||
74 | #define cvmx_le16_to_cpu le16_to_cpu | ||
75 | |||
76 | #define MAX_RETRIES 3 /* Maximum number of times to retry failed transactions */ | ||
77 | #define MAX_PIPES 32 /* Maximum number of pipes that can be open at once */ | ||
78 | #define MAX_TRANSACTIONS 256 /* Maximum number of outstanding transactions across all pipes */ | ||
79 | #define MAX_CHANNELS 8 /* Maximum number of hardware channels supported by the USB block */ | ||
80 | #define MAX_USB_ADDRESS 127 /* The highest valid USB device address */ | ||
81 | #define MAX_USB_ENDPOINT 15 /* The highest valid USB endpoint number */ | ||
82 | #define MAX_USB_HUB_PORT 15 /* The highest valid port number on a hub */ | ||
83 | #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 */ | ||
84 | #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 */ | ||
85 | |||
86 | /* These defines disable the normal read and write csr. This is so I can add | ||
87 | extra debug stuff to the usb specific version and I won't use the normal | ||
88 | version by mistake */ | ||
89 | #define cvmx_read_csr use_cvmx_usb_read_csr64_instead_of_cvmx_read_csr | ||
90 | #define cvmx_write_csr use_cvmx_usb_write_csr64_instead_of_cvmx_write_csr | ||
91 | |||
92 | typedef enum | ||
93 | { | ||
94 | __CVMX_USB_TRANSACTION_FLAGS_IN_USE = 1<<16, | ||
95 | } cvmx_usb_transaction_flags_t; | ||
96 | |||
97 | enum { | ||
98 | USB_CLOCK_TYPE_REF_12, | ||
99 | USB_CLOCK_TYPE_REF_24, | ||
100 | USB_CLOCK_TYPE_REF_48, | ||
101 | USB_CLOCK_TYPE_CRYSTAL_12, | ||
102 | }; | ||
103 | |||
104 | /** | ||
105 | * Logical transactions may take numerous low level | ||
106 | * transactions, especially when splits are concerned. This | ||
107 | * enum represents all of the possible stages a transaction can | ||
108 | * be in. Note that split completes are always even. This is so | ||
109 | * the NAK handler can backup to the previous low level | ||
110 | * transaction with a simple clearing of bit 0. | ||
111 | */ | ||
112 | typedef enum | ||
113 | { | ||
114 | CVMX_USB_STAGE_NON_CONTROL, | ||
115 | CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE, | ||
116 | CVMX_USB_STAGE_SETUP, | ||
117 | CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE, | ||
118 | CVMX_USB_STAGE_DATA, | ||
119 | CVMX_USB_STAGE_DATA_SPLIT_COMPLETE, | ||
120 | CVMX_USB_STAGE_STATUS, | ||
121 | CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE, | ||
122 | } cvmx_usb_stage_t; | ||
123 | |||
124 | /** | ||
125 | * This structure describes each pending USB transaction | ||
126 | * regardless of type. These are linked together to form a list | ||
127 | * of pending requests for a pipe. | ||
128 | */ | ||
129 | typedef struct cvmx_usb_transaction | ||
130 | { | ||
131 | struct cvmx_usb_transaction *prev; /**< Transaction before this one in the pipe */ | ||
132 | struct cvmx_usb_transaction *next; /**< Transaction after this one in the pipe */ | ||
133 | cvmx_usb_transfer_t type; /**< Type of transaction, duplicated of the pipe */ | ||
134 | cvmx_usb_transaction_flags_t flags; /**< State flags for this transaction */ | ||
135 | uint64_t buffer; /**< User's physical buffer address to read/write */ | ||
136 | int buffer_length; /**< Size of the user's buffer in bytes */ | ||
137 | uint64_t control_header; /**< For control transactions, physical address of the 8 byte standard header */ | ||
138 | int iso_start_frame; /**< For ISO transactions, the starting frame number */ | ||
139 | int iso_number_packets; /**< For ISO transactions, the number of packets in the request */ | ||
140 | cvmx_usb_iso_packet_t *iso_packets; /**< For ISO transactions, the sub packets in the request */ | ||
141 | int xfersize; | ||
142 | int pktcnt; | ||
143 | int retries; | ||
144 | int actual_bytes; /**< Actual bytes transfer for this transaction */ | ||
145 | cvmx_usb_stage_t stage; /**< For control transactions, the current stage */ | ||
146 | cvmx_usb_callback_func_t callback; /**< User's callback function when complete */ | ||
147 | void *callback_data; /**< User's data */ | ||
148 | } cvmx_usb_transaction_t; | ||
149 | |||
150 | /** | ||
151 | * A pipe represents a virtual connection between Octeon and some | ||
152 | * USB device. It contains a list of pending request to the device. | ||
153 | */ | ||
154 | typedef struct cvmx_usb_pipe | ||
155 | { | ||
156 | struct cvmx_usb_pipe *prev; /**< Pipe before this one in the list */ | ||
157 | struct cvmx_usb_pipe *next; /**< Pipe after this one in the list */ | ||
158 | cvmx_usb_transaction_t *head; /**< The first pending transaction */ | ||
159 | cvmx_usb_transaction_t *tail; /**< The last pending transaction */ | ||
160 | uint64_t interval; /**< For periodic pipes, the interval between packets in frames */ | ||
161 | uint64_t next_tx_frame; /**< The next frame this pipe is allowed to transmit on */ | ||
162 | cvmx_usb_pipe_flags_t flags; /**< State flags for this pipe */ | ||
163 | cvmx_usb_speed_t device_speed; /**< Speed of device connected to this pipe */ | ||
164 | cvmx_usb_transfer_t transfer_type; /**< Type of transaction supported by this pipe */ | ||
165 | cvmx_usb_direction_t transfer_dir; /**< IN or OUT. Ignored for Control */ | ||
166 | int multi_count; /**< Max packet in a row for the device */ | ||
167 | uint16_t max_packet; /**< The device's maximum packet size in bytes */ | ||
168 | uint8_t device_addr; /**< USB device address at other end of pipe */ | ||
169 | uint8_t endpoint_num; /**< USB endpoint number at other end of pipe */ | ||
170 | uint8_t hub_device_addr; /**< Hub address this device is connected to */ | ||
171 | uint8_t hub_port; /**< Hub port this device is connected to */ | ||
172 | uint8_t pid_toggle; /**< This toggles between 0/1 on every packet send to track the data pid needed */ | ||
173 | uint8_t channel; /**< Hardware DMA channel for this pipe */ | ||
174 | int8_t split_sc_frame; /**< The low order bits of the frame number the split complete should be sent on */ | ||
175 | } cvmx_usb_pipe_t; | ||
176 | |||
177 | typedef struct | ||
178 | { | ||
179 | cvmx_usb_pipe_t *head; /**< Head of the list, or NULL if empty */ | ||
180 | cvmx_usb_pipe_t *tail; /**< Tail if the list, or NULL if empty */ | ||
181 | } cvmx_usb_pipe_list_t; | ||
182 | |||
183 | typedef struct | ||
184 | { | ||
185 | struct | ||
186 | { | ||
187 | int channel; | ||
188 | int size; | ||
189 | uint64_t address; | ||
190 | } entry[MAX_CHANNELS+1]; | ||
191 | int head; | ||
192 | int tail; | ||
193 | } cvmx_usb_tx_fifo_t; | ||
194 | |||
195 | /** | ||
196 | * The state of the USB block is stored in this structure | ||
197 | */ | ||
198 | typedef struct | ||
199 | { | ||
200 | int init_flags; /**< Flags passed to initialize */ | ||
201 | int index; /**< Which USB block this is for */ | ||
202 | int idle_hardware_channels; /**< Bit set for every idle hardware channel */ | ||
203 | cvmx_usbcx_hprt_t usbcx_hprt; /**< Stored port status so we don't need to read a CSR to determine splits */ | ||
204 | cvmx_usb_pipe_t *pipe_for_channel[MAX_CHANNELS]; /**< Map channels to pipes */ | ||
205 | cvmx_usb_transaction_t *free_transaction_head; /**< List of free transactions head */ | ||
206 | cvmx_usb_transaction_t *free_transaction_tail; /**< List of free transactions tail */ | ||
207 | cvmx_usb_pipe_t pipe[MAX_PIPES]; /**< Storage for pipes */ | ||
208 | cvmx_usb_transaction_t transaction[MAX_TRANSACTIONS]; /**< Storage for transactions */ | ||
209 | cvmx_usb_callback_func_t callback[__CVMX_USB_CALLBACK_END]; /**< User global callbacks */ | ||
210 | void *callback_data[__CVMX_USB_CALLBACK_END]; /**< User data for each callback */ | ||
211 | int indent; /**< Used by debug output to indent functions */ | ||
212 | cvmx_usb_port_status_t port_status; /**< Last port status used for change notification */ | ||
213 | cvmx_usb_pipe_list_t free_pipes; /**< List of all pipes that are currently closed */ | ||
214 | cvmx_usb_pipe_list_t idle_pipes; /**< List of open pipes that have no transactions */ | ||
215 | cvmx_usb_pipe_list_t active_pipes[4]; /**< Active pipes indexed by transfer type */ | ||
216 | uint64_t frame_number; /**< Increments every SOF interrupt for time keeping */ | ||
217 | cvmx_usb_transaction_t *active_split; /**< Points to the current active split, or NULL */ | ||
218 | cvmx_usb_tx_fifo_t periodic; | ||
219 | cvmx_usb_tx_fifo_t nonperiodic; | ||
220 | } cvmx_usb_internal_state_t; | ||
221 | |||
222 | /* This macro logs out whenever a function is called if debugging is on */ | ||
223 | #define CVMX_USB_LOG_CALLED() \ | ||
224 | if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CALLS)) \ | ||
225 | cvmx_dprintf("%*s%s: called\n", 2*usb->indent++, "", __FUNCTION__); | ||
226 | |||
227 | /* This macro logs out each function parameter if debugging is on */ | ||
228 | #define CVMX_USB_LOG_PARAM(format, param) \ | ||
229 | if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CALLS)) \ | ||
230 | cvmx_dprintf("%*s%s: param %s = " format "\n", 2*usb->indent, "", __FUNCTION__, #param, param); | ||
231 | |||
232 | /* This macro logs out when a function returns a value */ | ||
233 | #define CVMX_USB_RETURN(v) \ | ||
234 | do { \ | ||
235 | typeof(v) r = v; \ | ||
236 | if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CALLS)) \ | ||
237 | cvmx_dprintf("%*s%s: returned %s(%d)\n", 2*--usb->indent, "", __FUNCTION__, #v, r); \ | ||
238 | return r; \ | ||
239 | } while (0); | ||
240 | |||
241 | /* This macro logs out when a function doesn't return a value */ | ||
242 | #define CVMX_USB_RETURN_NOTHING() \ | ||
243 | do { \ | ||
244 | if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CALLS)) \ | ||
245 | cvmx_dprintf("%*s%s: returned\n", 2*--usb->indent, "", __FUNCTION__); \ | ||
246 | return; \ | ||
247 | } while (0); | ||
248 | |||
249 | /* This macro spins on a field waiting for it to reach a value */ | ||
250 | #define CVMX_WAIT_FOR_FIELD32(address, type, field, op, value, timeout_usec)\ | ||
251 | ({int result; \ | ||
252 | do { \ | ||
253 | uint64_t done = cvmx_get_cycle() + (uint64_t)timeout_usec * \ | ||
254 | octeon_get_clock_rate() / 1000000; \ | ||
255 | type c; \ | ||
256 | while (1) \ | ||
257 | { \ | ||
258 | c.u32 = __cvmx_usb_read_csr32(usb, address); \ | ||
259 | if (c.s.field op (value)) { \ | ||
260 | result = 0; \ | ||
261 | break; \ | ||
262 | } else if (cvmx_get_cycle() > done) { \ | ||
263 | result = -1; \ | ||
264 | break; \ | ||
265 | } else \ | ||
266 | cvmx_wait(100); \ | ||
267 | } \ | ||
268 | } while (0); \ | ||
269 | result;}) | ||
270 | |||
271 | /* This macro logically sets a single field in a CSR. It does the sequence | ||
272 | read, modify, and write */ | ||
273 | #define USB_SET_FIELD32(address, type, field, value)\ | ||
274 | do { \ | ||
275 | type c; \ | ||
276 | c.u32 = __cvmx_usb_read_csr32(usb, address);\ | ||
277 | c.s.field = value; \ | ||
278 | __cvmx_usb_write_csr32(usb, address, c.u32);\ | ||
279 | } while (0) | ||
280 | |||
281 | /* Returns the IO address to push/pop stuff data from the FIFOs */ | ||
282 | #define USB_FIFO_ADDRESS(channel, usb_index) (CVMX_USBCX_GOTGCTL(usb_index) + ((channel)+1)*0x1000) | ||
283 | |||
284 | static int octeon_usb_get_clock_type(void) | ||
285 | { | ||
286 | switch (cvmx_sysinfo_get()->board_type) { | ||
287 | case CVMX_BOARD_TYPE_BBGW_REF: | ||
288 | case CVMX_BOARD_TYPE_LANAI2_A: | ||
289 | case CVMX_BOARD_TYPE_LANAI2_U: | ||
290 | case CVMX_BOARD_TYPE_LANAI2_G: | ||
291 | return USB_CLOCK_TYPE_CRYSTAL_12; | ||
292 | } | ||
293 | |||
294 | /* FIXME: This should use CVMX_BOARD_TYPE_UBNT_E100 */ | ||
295 | if (OCTEON_IS_MODEL(OCTEON_CN50XX) && | ||
296 | cvmx_sysinfo_get()->board_type == 20002) | ||
297 | return USB_CLOCK_TYPE_CRYSTAL_12; | ||
298 | |||
299 | return USB_CLOCK_TYPE_REF_48; | ||
300 | } | ||
301 | |||
302 | /** | ||
303 | * @INTERNAL | ||
304 | * Read a USB 32bit CSR. It performs the necessary address swizzle | ||
305 | * for 32bit CSRs and logs the value in a readable format if | ||
306 | * debugging is on. | ||
307 | * | ||
308 | * @param usb USB block this access is for | ||
309 | * @param address 64bit address to read | ||
310 | * | ||
311 | * @return Result of the read | ||
312 | */ | ||
313 | static inline uint32_t __cvmx_usb_read_csr32(cvmx_usb_internal_state_t *usb, | ||
314 | uint64_t address) | ||
315 | { | ||
316 | uint32_t result = cvmx_read64_uint32(address ^ 4); | ||
317 | return result; | ||
318 | } | ||
319 | |||
320 | |||
321 | /** | ||
322 | * @INTERNAL | ||
323 | * Write a USB 32bit CSR. It performs the necessary address | ||
324 | * swizzle for 32bit CSRs and logs the value in a readable format | ||
325 | * if debugging is on. | ||
326 | * | ||
327 | * @param usb USB block this access is for | ||
328 | * @param address 64bit address to write | ||
329 | * @param value Value to write | ||
330 | */ | ||
331 | static inline void __cvmx_usb_write_csr32(cvmx_usb_internal_state_t *usb, | ||
332 | uint64_t address, uint32_t value) | ||
333 | { | ||
334 | cvmx_write64_uint32(address ^ 4, value); | ||
335 | cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index)); | ||
336 | } | ||
337 | |||
338 | |||
339 | /** | ||
340 | * @INTERNAL | ||
341 | * Read a USB 64bit CSR. It logs the value in a readable format if | ||
342 | * debugging is on. | ||
343 | * | ||
344 | * @param usb USB block this access is for | ||
345 | * @param address 64bit address to read | ||
346 | * | ||
347 | * @return Result of the read | ||
348 | */ | ||
349 | static inline uint64_t __cvmx_usb_read_csr64(cvmx_usb_internal_state_t *usb, | ||
350 | uint64_t address) | ||
351 | { | ||
352 | uint64_t result = cvmx_read64_uint64(address); | ||
353 | return result; | ||
354 | } | ||
355 | |||
356 | |||
357 | /** | ||
358 | * @INTERNAL | ||
359 | * Write a USB 64bit CSR. It logs the value in a readable format | ||
360 | * if debugging is on. | ||
361 | * | ||
362 | * @param usb USB block this access is for | ||
363 | * @param address 64bit address to write | ||
364 | * @param value Value to write | ||
365 | */ | ||
366 | static inline void __cvmx_usb_write_csr64(cvmx_usb_internal_state_t *usb, | ||
367 | uint64_t address, uint64_t value) | ||
368 | { | ||
369 | cvmx_write64_uint64(address, value); | ||
370 | } | ||
371 | |||
372 | |||
373 | /** | ||
374 | * @INTERNAL | ||
375 | * Utility function to convert complete codes into strings | ||
376 | * | ||
377 | * @param complete_code | ||
378 | * Code to convert | ||
379 | * | ||
380 | * @return Human readable string | ||
381 | */ | ||
382 | static const char *__cvmx_usb_complete_to_string(cvmx_usb_complete_t complete_code) | ||
383 | { | ||
384 | switch (complete_code) | ||
385 | { | ||
386 | case CVMX_USB_COMPLETE_SUCCESS: return "SUCCESS"; | ||
387 | case CVMX_USB_COMPLETE_SHORT: return "SHORT"; | ||
388 | case CVMX_USB_COMPLETE_CANCEL: return "CANCEL"; | ||
389 | case CVMX_USB_COMPLETE_ERROR: return "ERROR"; | ||
390 | case CVMX_USB_COMPLETE_STALL: return "STALL"; | ||
391 | case CVMX_USB_COMPLETE_XACTERR: return "XACTERR"; | ||
392 | case CVMX_USB_COMPLETE_DATATGLERR: return "DATATGLERR"; | ||
393 | case CVMX_USB_COMPLETE_BABBLEERR: return "BABBLEERR"; | ||
394 | case CVMX_USB_COMPLETE_FRAMEERR: return "FRAMEERR"; | ||
395 | } | ||
396 | return "Update __cvmx_usb_complete_to_string"; | ||
397 | } | ||
398 | |||
399 | |||
400 | /** | ||
401 | * @INTERNAL | ||
402 | * Return non zero if this pipe connects to a non HIGH speed | ||
403 | * device through a high speed hub. | ||
404 | * | ||
405 | * @param usb USB block this access is for | ||
406 | * @param pipe Pipe to check | ||
407 | * | ||
408 | * @return Non zero if we need to do split transactions | ||
409 | */ | ||
410 | static inline int __cvmx_usb_pipe_needs_split(cvmx_usb_internal_state_t *usb, cvmx_usb_pipe_t *pipe) | ||
411 | { | ||
412 | return ((pipe->device_speed != CVMX_USB_SPEED_HIGH) && (usb->usbcx_hprt.s.prtspd == CVMX_USB_SPEED_HIGH)); | ||
413 | } | ||
414 | |||
415 | |||
416 | /** | ||
417 | * @INTERNAL | ||
418 | * Trivial utility function to return the correct PID for a pipe | ||
419 | * | ||
420 | * @param pipe pipe to check | ||
421 | * | ||
422 | * @return PID for pipe | ||
423 | */ | ||
424 | static inline int __cvmx_usb_get_data_pid(cvmx_usb_pipe_t *pipe) | ||
425 | { | ||
426 | if (pipe->pid_toggle) | ||
427 | return 2; /* Data1 */ | ||
428 | else | ||
429 | return 0; /* Data0 */ | ||
430 | } | ||
431 | |||
432 | |||
433 | /** | ||
434 | * Return the number of USB ports supported by this Octeon | ||
435 | * chip. If the chip doesn't support USB, or is not supported | ||
436 | * by this API, a zero will be returned. Most Octeon chips | ||
437 | * support one usb port, but some support two ports. | ||
438 | * cvmx_usb_initialize() must be called on independent | ||
439 | * cvmx_usb_state_t structures. | ||
440 | * | ||
441 | * @return Number of port, zero if usb isn't supported | ||
442 | */ | ||
443 | int cvmx_usb_get_num_ports(void) | ||
444 | { | ||
445 | int arch_ports = 0; | ||
446 | |||
447 | if (OCTEON_IS_MODEL(OCTEON_CN56XX)) | ||
448 | arch_ports = 1; | ||
449 | else if (OCTEON_IS_MODEL(OCTEON_CN52XX)) | ||
450 | arch_ports = 2; | ||
451 | else if (OCTEON_IS_MODEL(OCTEON_CN50XX)) | ||
452 | arch_ports = 1; | ||
453 | else if (OCTEON_IS_MODEL(OCTEON_CN31XX)) | ||
454 | arch_ports = 1; | ||
455 | else if (OCTEON_IS_MODEL(OCTEON_CN30XX)) | ||
456 | arch_ports = 1; | ||
457 | else | ||
458 | arch_ports = 0; | ||
459 | |||
460 | return arch_ports; | ||
461 | } | ||
462 | |||
463 | |||
464 | /** | ||
465 | * @INTERNAL | ||
466 | * Allocate a usb transaction for use | ||
467 | * | ||
468 | * @param usb USB device state populated by | ||
469 | * cvmx_usb_initialize(). | ||
470 | * | ||
471 | * @return Transaction or NULL | ||
472 | */ | ||
473 | static inline cvmx_usb_transaction_t *__cvmx_usb_alloc_transaction(cvmx_usb_internal_state_t *usb) | ||
474 | { | ||
475 | cvmx_usb_transaction_t *t; | ||
476 | t = usb->free_transaction_head; | ||
477 | if (t) | ||
478 | { | ||
479 | usb->free_transaction_head = t->next; | ||
480 | if (!usb->free_transaction_head) | ||
481 | usb->free_transaction_tail = NULL; | ||
482 | } | ||
483 | else if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO)) | ||
484 | cvmx_dprintf("%s: Failed to allocate a transaction\n", __FUNCTION__); | ||
485 | if (t) | ||
486 | { | ||
487 | memset(t, 0, sizeof(*t)); | ||
488 | t->flags = __CVMX_USB_TRANSACTION_FLAGS_IN_USE; | ||
489 | } | ||
490 | return t; | ||
491 | } | ||
492 | |||
493 | |||
494 | /** | ||
495 | * @INTERNAL | ||
496 | * Free a usb transaction | ||
497 | * | ||
498 | * @param usb USB device state populated by | ||
499 | * cvmx_usb_initialize(). | ||
500 | * @param transaction | ||
501 | * Transaction to free | ||
502 | */ | ||
503 | static inline void __cvmx_usb_free_transaction(cvmx_usb_internal_state_t *usb, | ||
504 | cvmx_usb_transaction_t *transaction) | ||
505 | { | ||
506 | transaction->flags = 0; | ||
507 | transaction->prev = NULL; | ||
508 | transaction->next = NULL; | ||
509 | if (usb->free_transaction_tail) | ||
510 | usb->free_transaction_tail->next = transaction; | ||
511 | else | ||
512 | usb->free_transaction_head = transaction; | ||
513 | usb->free_transaction_tail = transaction; | ||
514 | } | ||
515 | |||
516 | |||
517 | /** | ||
518 | * @INTERNAL | ||
519 | * Add a pipe to the tail of a list | ||
520 | * @param list List to add pipe to | ||
521 | * @param pipe Pipe to add | ||
522 | */ | ||
523 | static inline void __cvmx_usb_append_pipe(cvmx_usb_pipe_list_t *list, cvmx_usb_pipe_t *pipe) | ||
524 | { | ||
525 | pipe->next = NULL; | ||
526 | pipe->prev = list->tail; | ||
527 | if (list->tail) | ||
528 | list->tail->next = pipe; | ||
529 | else | ||
530 | list->head = pipe; | ||
531 | list->tail = pipe; | ||
532 | } | ||
533 | |||
534 | |||
535 | /** | ||
536 | * @INTERNAL | ||
537 | * Remove a pipe from a list | ||
538 | * @param list List to remove pipe from | ||
539 | * @param pipe Pipe to remove | ||
540 | */ | ||
541 | static inline void __cvmx_usb_remove_pipe(cvmx_usb_pipe_list_t *list, cvmx_usb_pipe_t *pipe) | ||
542 | { | ||
543 | if (list->head == pipe) | ||
544 | { | ||
545 | list->head = pipe->next; | ||
546 | pipe->next = NULL; | ||
547 | if (list->head) | ||
548 | list->head->prev = NULL; | ||
549 | else | ||
550 | list->tail = NULL; | ||
551 | } | ||
552 | else if (list->tail == pipe) | ||
553 | { | ||
554 | list->tail = pipe->prev; | ||
555 | list->tail->next = NULL; | ||
556 | pipe->prev = NULL; | ||
557 | } | ||
558 | else | ||
559 | { | ||
560 | pipe->prev->next = pipe->next; | ||
561 | pipe->next->prev = pipe->prev; | ||
562 | pipe->prev = NULL; | ||
563 | pipe->next = NULL; | ||
564 | } | ||
565 | } | ||
566 | |||
567 | |||
568 | /** | ||
569 | * Initialize a USB port for use. This must be called before any | ||
570 | * other access to the Octeon USB port is made. The port starts | ||
571 | * off in the disabled state. | ||
572 | * | ||
573 | * @param state Pointer to an empty cvmx_usb_state_t structure | ||
574 | * that will be populated by the initialize call. | ||
575 | * This structure is then passed to all other USB | ||
576 | * functions. | ||
577 | * @param usb_port_number | ||
578 | * Which Octeon USB port to initialize. | ||
579 | * @param flags Flags to control hardware initialization. See | ||
580 | * cvmx_usb_initialize_flags_t for the flag | ||
581 | * definitions. Some flags are mandatory. | ||
582 | * | ||
583 | * @return CVMX_USB_SUCCESS or a negative error code defined in | ||
584 | * cvmx_usb_status_t. | ||
585 | */ | ||
586 | cvmx_usb_status_t cvmx_usb_initialize(cvmx_usb_state_t *state, | ||
587 | int usb_port_number, | ||
588 | cvmx_usb_initialize_flags_t flags) | ||
589 | { | ||
590 | cvmx_usbnx_clk_ctl_t usbn_clk_ctl; | ||
591 | cvmx_usbnx_usbp_ctl_status_t usbn_usbp_ctl_status; | ||
592 | cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state; | ||
593 | |||
594 | usb->init_flags = flags; | ||
595 | CVMX_USB_LOG_CALLED(); | ||
596 | CVMX_USB_LOG_PARAM("%p", state); | ||
597 | CVMX_USB_LOG_PARAM("%d", usb_port_number); | ||
598 | CVMX_USB_LOG_PARAM("0x%x", flags); | ||
599 | |||
600 | /* Make sure that state is large enough to store the internal state */ | ||
601 | if (sizeof(*state) < sizeof(*usb)) | ||
602 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
603 | /* At first allow 0-1 for the usb port number */ | ||
604 | if ((usb_port_number < 0) || (usb_port_number > 1)) | ||
605 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
606 | /* For all chips except 52XX there is only one port */ | ||
607 | if (!OCTEON_IS_MODEL(OCTEON_CN52XX) && (usb_port_number > 0)) | ||
608 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
609 | /* Try to determine clock type automatically */ | ||
610 | if ((flags & (CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI | | ||
611 | CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND)) == 0) | ||
612 | { | ||
613 | if (octeon_usb_get_clock_type() == USB_CLOCK_TYPE_CRYSTAL_12) | ||
614 | flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI; /* Only 12 MHZ crystals are supported */ | ||
615 | else | ||
616 | flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND; | ||
617 | } | ||
618 | |||
619 | if (flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND) | ||
620 | { | ||
621 | /* Check for auto ref clock frequency */ | ||
622 | if (!(flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK)) | ||
623 | switch (octeon_usb_get_clock_type()) | ||
624 | { | ||
625 | case USB_CLOCK_TYPE_REF_12: | ||
626 | flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ; | ||
627 | break; | ||
628 | case USB_CLOCK_TYPE_REF_24: | ||
629 | flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ; | ||
630 | break; | ||
631 | case USB_CLOCK_TYPE_REF_48: | ||
632 | flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ; | ||
633 | break; | ||
634 | default: | ||
635 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
636 | break; | ||
637 | } | ||
638 | } | ||
639 | |||
640 | memset(usb, 0, sizeof(usb)); | ||
641 | usb->init_flags = flags; | ||
642 | |||
643 | /* Initialize the USB state structure */ | ||
644 | { | ||
645 | int i; | ||
646 | usb->index = usb_port_number; | ||
647 | |||
648 | /* Initialize the transaction double linked list */ | ||
649 | usb->free_transaction_head = NULL; | ||
650 | usb->free_transaction_tail = NULL; | ||
651 | for (i=0; i<MAX_TRANSACTIONS; i++) | ||
652 | __cvmx_usb_free_transaction(usb, usb->transaction + i); | ||
653 | for (i=0; i<MAX_PIPES; i++) | ||
654 | __cvmx_usb_append_pipe(&usb->free_pipes, usb->pipe + i); | ||
655 | } | ||
656 | |||
657 | /* Power On Reset and PHY Initialization */ | ||
658 | |||
659 | /* 1. Wait for DCOK to assert (nothing to do) */ | ||
660 | /* 2a. Write USBN0/1_CLK_CTL[POR] = 1 and | ||
661 | USBN0/1_CLK_CTL[HRST,PRST,HCLK_RST] = 0 */ | ||
662 | usbn_clk_ctl.u64 = __cvmx_usb_read_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index)); | ||
663 | usbn_clk_ctl.s.por = 1; | ||
664 | usbn_clk_ctl.s.hrst = 0; | ||
665 | usbn_clk_ctl.s.prst = 0; | ||
666 | usbn_clk_ctl.s.hclk_rst = 0; | ||
667 | usbn_clk_ctl.s.enable = 0; | ||
668 | /* 2b. Select the USB reference clock/crystal parameters by writing | ||
669 | appropriate values to USBN0/1_CLK_CTL[P_C_SEL, P_RTYPE, P_COM_ON] */ | ||
670 | if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND) | ||
671 | { | ||
672 | /* The USB port uses 12/24/48MHz 2.5V board clock | ||
673 | source at USB_XO. USB_XI should be tied to GND. | ||
674 | Most Octeon evaluation boards require this setting */ | ||
675 | if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) | ||
676 | { | ||
677 | usbn_clk_ctl.cn31xx.p_rclk = 1; /* From CN31XX,CN30XX manual */ | ||
678 | usbn_clk_ctl.cn31xx.p_xenbn = 0; | ||
679 | } | ||
680 | else if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN50XX)) | ||
681 | usbn_clk_ctl.cn56xx.p_rtype = 2; /* From CN56XX,CN50XX manual */ | ||
682 | else | ||
683 | usbn_clk_ctl.cn52xx.p_rtype = 1; /* From CN52XX manual */ | ||
684 | |||
685 | switch (flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK) | ||
686 | { | ||
687 | case CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ: | ||
688 | usbn_clk_ctl.s.p_c_sel = 0; | ||
689 | break; | ||
690 | case CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ: | ||
691 | usbn_clk_ctl.s.p_c_sel = 1; | ||
692 | break; | ||
693 | case CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ: | ||
694 | usbn_clk_ctl.s.p_c_sel = 2; | ||
695 | break; | ||
696 | } | ||
697 | } | ||
698 | else | ||
699 | { | ||
700 | /* The USB port uses a 12MHz crystal as clock source | ||
701 | at USB_XO and USB_XI */ | ||
702 | if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) | ||
703 | { | ||
704 | usbn_clk_ctl.cn31xx.p_rclk = 1; /* From CN31XX,CN30XX manual */ | ||
705 | usbn_clk_ctl.cn31xx.p_xenbn = 1; | ||
706 | } | ||
707 | else if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN50XX)) | ||
708 | usbn_clk_ctl.cn56xx.p_rtype = 0; /* From CN56XX,CN50XX manual */ | ||
709 | else | ||
710 | usbn_clk_ctl.cn52xx.p_rtype = 0; /* From CN52XX manual */ | ||
711 | |||
712 | usbn_clk_ctl.s.p_c_sel = 0; | ||
713 | } | ||
714 | /* 2c. Select the HCLK via writing USBN0/1_CLK_CTL[DIVIDE, DIVIDE2] and | ||
715 | setting USBN0/1_CLK_CTL[ENABLE] = 1. Divide the core clock down such | ||
716 | that USB is as close as possible to 125Mhz */ | ||
717 | { | ||
718 | int divisor = (octeon_get_clock_rate()+125000000-1)/125000000; | ||
719 | if (divisor < 4) /* Lower than 4 doesn't seem to work properly */ | ||
720 | divisor = 4; | ||
721 | usbn_clk_ctl.s.divide = divisor; | ||
722 | usbn_clk_ctl.s.divide2 = 0; | ||
723 | } | ||
724 | __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index), | ||
725 | usbn_clk_ctl.u64); | ||
726 | /* 2d. Write USBN0/1_CLK_CTL[HCLK_RST] = 1 */ | ||
727 | usbn_clk_ctl.s.hclk_rst = 1; | ||
728 | __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index), | ||
729 | usbn_clk_ctl.u64); | ||
730 | /* 2e. Wait 64 core-clock cycles for HCLK to stabilize */ | ||
731 | cvmx_wait(64); | ||
732 | /* 3. Program the power-on reset field in the USBN clock-control register: | ||
733 | USBN_CLK_CTL[POR] = 0 */ | ||
734 | usbn_clk_ctl.s.por = 0; | ||
735 | __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index), | ||
736 | usbn_clk_ctl.u64); | ||
737 | /* 4. Wait 1 ms for PHY clock to start */ | ||
738 | cvmx_wait_usec(1000); | ||
739 | /* 5. Program the Reset input from automatic test equipment field in the | ||
740 | USBP control and status register: USBN_USBP_CTL_STATUS[ATE_RESET] = 1 */ | ||
741 | usbn_usbp_ctl_status.u64 = __cvmx_usb_read_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index)); | ||
742 | usbn_usbp_ctl_status.s.ate_reset = 1; | ||
743 | __cvmx_usb_write_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index), | ||
744 | usbn_usbp_ctl_status.u64); | ||
745 | /* 6. Wait 10 cycles */ | ||
746 | cvmx_wait(10); | ||
747 | /* 7. Clear ATE_RESET field in the USBN clock-control register: | ||
748 | USBN_USBP_CTL_STATUS[ATE_RESET] = 0 */ | ||
749 | usbn_usbp_ctl_status.s.ate_reset = 0; | ||
750 | __cvmx_usb_write_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index), | ||
751 | usbn_usbp_ctl_status.u64); | ||
752 | /* 8. Program the PHY reset field in the USBN clock-control register: | ||
753 | USBN_CLK_CTL[PRST] = 1 */ | ||
754 | usbn_clk_ctl.s.prst = 1; | ||
755 | __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index), | ||
756 | usbn_clk_ctl.u64); | ||
757 | /* 9. Program the USBP control and status register to select host or | ||
758 | device mode. USBN_USBP_CTL_STATUS[HST_MODE] = 0 for host, = 1 for | ||
759 | device */ | ||
760 | usbn_usbp_ctl_status.s.hst_mode = 0; | ||
761 | __cvmx_usb_write_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index), | ||
762 | usbn_usbp_ctl_status.u64); | ||
763 | /* 10. Wait 1 us */ | ||
764 | cvmx_wait_usec(1); | ||
765 | /* 11. Program the hreset_n field in the USBN clock-control register: | ||
766 | USBN_CLK_CTL[HRST] = 1 */ | ||
767 | usbn_clk_ctl.s.hrst = 1; | ||
768 | __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index), | ||
769 | usbn_clk_ctl.u64); | ||
770 | /* 12. Proceed to USB core initialization */ | ||
771 | usbn_clk_ctl.s.enable = 1; | ||
772 | __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index), | ||
773 | usbn_clk_ctl.u64); | ||
774 | cvmx_wait_usec(1); | ||
775 | |||
776 | /* USB Core Initialization */ | ||
777 | |||
778 | /* 1. Read USBC_GHWCFG1, USBC_GHWCFG2, USBC_GHWCFG3, USBC_GHWCFG4 to | ||
779 | determine USB core configuration parameters. */ | ||
780 | /* Nothing needed */ | ||
781 | /* 2. Program the following fields in the global AHB configuration | ||
782 | register (USBC_GAHBCFG) | ||
783 | DMA mode, USBC_GAHBCFG[DMAEn]: 1 = DMA mode, 0 = slave mode | ||
784 | Burst length, USBC_GAHBCFG[HBSTLEN] = 0 | ||
785 | Nonperiodic TxFIFO empty level (slave mode only), | ||
786 | USBC_GAHBCFG[NPTXFEMPLVL] | ||
787 | Periodic TxFIFO empty level (slave mode only), | ||
788 | USBC_GAHBCFG[PTXFEMPLVL] | ||
789 | Global interrupt mask, USBC_GAHBCFG[GLBLINTRMSK] = 1 */ | ||
790 | { | ||
791 | cvmx_usbcx_gahbcfg_t usbcx_gahbcfg; | ||
792 | /* Due to an errata, CN31XX doesn't support DMA */ | ||
793 | if (OCTEON_IS_MODEL(OCTEON_CN31XX)) | ||
794 | usb->init_flags |= CVMX_USB_INITIALIZE_FLAGS_NO_DMA; | ||
795 | usbcx_gahbcfg.u32 = 0; | ||
796 | usbcx_gahbcfg.s.dmaen = !(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA); | ||
797 | if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA) | ||
798 | usb->idle_hardware_channels = 0x1; /* Only use one channel with non DMA */ | ||
799 | else if (OCTEON_IS_MODEL(OCTEON_CN5XXX)) | ||
800 | usb->idle_hardware_channels = 0xf7; /* CN5XXX have an errata with channel 3 */ | ||
801 | else | ||
802 | usb->idle_hardware_channels = 0xff; | ||
803 | usbcx_gahbcfg.s.hbstlen = 0; | ||
804 | usbcx_gahbcfg.s.nptxfemplvl = 1; | ||
805 | usbcx_gahbcfg.s.ptxfemplvl = 1; | ||
806 | usbcx_gahbcfg.s.glblintrmsk = 1; | ||
807 | __cvmx_usb_write_csr32(usb, CVMX_USBCX_GAHBCFG(usb->index), | ||
808 | usbcx_gahbcfg.u32); | ||
809 | } | ||
810 | /* 3. Program the following fields in USBC_GUSBCFG register. | ||
811 | HS/FS timeout calibration, USBC_GUSBCFG[TOUTCAL] = 0 | ||
812 | ULPI DDR select, USBC_GUSBCFG[DDRSEL] = 0 | ||
813 | USB turnaround time, USBC_GUSBCFG[USBTRDTIM] = 0x5 | ||
814 | PHY low-power clock select, USBC_GUSBCFG[PHYLPWRCLKSEL] = 0 */ | ||
815 | { | ||
816 | cvmx_usbcx_gusbcfg_t usbcx_gusbcfg; | ||
817 | usbcx_gusbcfg.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GUSBCFG(usb->index)); | ||
818 | usbcx_gusbcfg.s.toutcal = 0; | ||
819 | usbcx_gusbcfg.s.ddrsel = 0; | ||
820 | usbcx_gusbcfg.s.usbtrdtim = 0x5; | ||
821 | usbcx_gusbcfg.s.phylpwrclksel = 0; | ||
822 | __cvmx_usb_write_csr32(usb, CVMX_USBCX_GUSBCFG(usb->index), | ||
823 | usbcx_gusbcfg.u32); | ||
824 | } | ||
825 | /* 4. The software must unmask the following bits in the USBC_GINTMSK | ||
826 | register. | ||
827 | OTG interrupt mask, USBC_GINTMSK[OTGINTMSK] = 1 | ||
828 | Mode mismatch interrupt mask, USBC_GINTMSK[MODEMISMSK] = 1 */ | ||
829 | { | ||
830 | cvmx_usbcx_gintmsk_t usbcx_gintmsk; | ||
831 | int channel; | ||
832 | |||
833 | usbcx_gintmsk.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GINTMSK(usb->index)); | ||
834 | usbcx_gintmsk.s.otgintmsk = 1; | ||
835 | usbcx_gintmsk.s.modemismsk = 1; | ||
836 | usbcx_gintmsk.s.hchintmsk = 1; | ||
837 | usbcx_gintmsk.s.sofmsk = 0; | ||
838 | /* We need RX FIFO interrupts if we don't have DMA */ | ||
839 | if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA) | ||
840 | usbcx_gintmsk.s.rxflvlmsk = 1; | ||
841 | __cvmx_usb_write_csr32(usb, CVMX_USBCX_GINTMSK(usb->index), | ||
842 | usbcx_gintmsk.u32); | ||
843 | |||
844 | /* Disable all channel interrupts. We'll enable them per channel later */ | ||
845 | for (channel=0; channel<8; channel++) | ||
846 | __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), 0); | ||
847 | } | ||
848 | |||
849 | { | ||
850 | /* Host Port Initialization */ | ||
851 | if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO)) | ||
852 | cvmx_dprintf("%s: USB%d is in host mode\n", __FUNCTION__, usb->index); | ||
853 | |||
854 | /* 1. Program the host-port interrupt-mask field to unmask, | ||
855 | USBC_GINTMSK[PRTINT] = 1 */ | ||
856 | USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), cvmx_usbcx_gintmsk_t, | ||
857 | prtintmsk, 1); | ||
858 | USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), cvmx_usbcx_gintmsk_t, | ||
859 | disconnintmsk, 1); | ||
860 | /* 2. Program the USBC_HCFG register to select full-speed host or | ||
861 | high-speed host. */ | ||
862 | { | ||
863 | cvmx_usbcx_hcfg_t usbcx_hcfg; | ||
864 | usbcx_hcfg.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCFG(usb->index)); | ||
865 | usbcx_hcfg.s.fslssupp = 0; | ||
866 | usbcx_hcfg.s.fslspclksel = 0; | ||
867 | __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCFG(usb->index), usbcx_hcfg.u32); | ||
868 | } | ||
869 | /* 3. Program the port power bit to drive VBUS on the USB, | ||
870 | USBC_HPRT[PRTPWR] = 1 */ | ||
871 | USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), cvmx_usbcx_hprt_t, prtpwr, 1); | ||
872 | |||
873 | /* Steps 4-15 from the manual are done later in the port enable */ | ||
874 | } | ||
875 | |||
876 | CVMX_USB_RETURN(CVMX_USB_SUCCESS); | ||
877 | } | ||
878 | |||
879 | |||
880 | /** | ||
881 | * Shutdown a USB port after a call to cvmx_usb_initialize(). | ||
882 | * The port should be disabled with all pipes closed when this | ||
883 | * function is called. | ||
884 | * | ||
885 | * @param state USB device state populated by | ||
886 | * cvmx_usb_initialize(). | ||
887 | * | ||
888 | * @return CVMX_USB_SUCCESS or a negative error code defined in | ||
889 | * cvmx_usb_status_t. | ||
890 | */ | ||
891 | cvmx_usb_status_t cvmx_usb_shutdown(cvmx_usb_state_t *state) | ||
892 | { | ||
893 | cvmx_usbnx_clk_ctl_t usbn_clk_ctl; | ||
894 | cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state; | ||
895 | |||
896 | CVMX_USB_LOG_CALLED(); | ||
897 | CVMX_USB_LOG_PARAM("%p", state); | ||
898 | |||
899 | /* Make sure all pipes are closed */ | ||
900 | if (usb->idle_pipes.head || | ||
901 | usb->active_pipes[CVMX_USB_TRANSFER_ISOCHRONOUS].head || | ||
902 | usb->active_pipes[CVMX_USB_TRANSFER_INTERRUPT].head || | ||
903 | usb->active_pipes[CVMX_USB_TRANSFER_CONTROL].head || | ||
904 | usb->active_pipes[CVMX_USB_TRANSFER_BULK].head) | ||
905 | CVMX_USB_RETURN(CVMX_USB_BUSY); | ||
906 | |||
907 | /* Disable the clocks and put them in power on reset */ | ||
908 | usbn_clk_ctl.u64 = __cvmx_usb_read_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index)); | ||
909 | usbn_clk_ctl.s.enable = 1; | ||
910 | usbn_clk_ctl.s.por = 1; | ||
911 | usbn_clk_ctl.s.hclk_rst = 1; | ||
912 | usbn_clk_ctl.s.prst = 0; | ||
913 | usbn_clk_ctl.s.hrst = 0; | ||
914 | __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index), | ||
915 | usbn_clk_ctl.u64); | ||
916 | CVMX_USB_RETURN(CVMX_USB_SUCCESS); | ||
917 | } | ||
918 | |||
919 | |||
920 | /** | ||
921 | * Enable a USB port. After this call succeeds, the USB port is | ||
922 | * online and servicing requests. | ||
923 | * | ||
924 | * @param state USB device state populated by | ||
925 | * cvmx_usb_initialize(). | ||
926 | * | ||
927 | * @return CVMX_USB_SUCCESS or a negative error code defined in | ||
928 | * cvmx_usb_status_t. | ||
929 | */ | ||
930 | cvmx_usb_status_t cvmx_usb_enable(cvmx_usb_state_t *state) | ||
931 | { | ||
932 | cvmx_usbcx_ghwcfg3_t usbcx_ghwcfg3; | ||
933 | cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state; | ||
934 | |||
935 | CVMX_USB_LOG_CALLED(); | ||
936 | CVMX_USB_LOG_PARAM("%p", state); | ||
937 | |||
938 | usb->usbcx_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index)); | ||
939 | |||
940 | /* If the port is already enabled the just return. We don't need to do | ||
941 | anything */ | ||
942 | if (usb->usbcx_hprt.s.prtena) | ||
943 | CVMX_USB_RETURN(CVMX_USB_SUCCESS); | ||
944 | |||
945 | /* If there is nothing plugged into the port then fail immediately */ | ||
946 | if (!usb->usbcx_hprt.s.prtconnsts) | ||
947 | { | ||
948 | if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO)) | ||
949 | cvmx_dprintf("%s: USB%d Nothing plugged into the port\n", __FUNCTION__, usb->index); | ||
950 | CVMX_USB_RETURN(CVMX_USB_TIMEOUT); | ||
951 | } | ||
952 | |||
953 | /* Program the port reset bit to start the reset process */ | ||
954 | USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), cvmx_usbcx_hprt_t, prtrst, 1); | ||
955 | |||
956 | /* Wait at least 50ms (high speed), or 10ms (full speed) for the reset | ||
957 | process to complete. */ | ||
958 | cvmx_wait_usec(50000); | ||
959 | |||
960 | /* Program the port reset bit to 0, USBC_HPRT[PRTRST] = 0 */ | ||
961 | USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), cvmx_usbcx_hprt_t, prtrst, 0); | ||
962 | |||
963 | /* Wait for the USBC_HPRT[PRTENA]. */ | ||
964 | if (CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_HPRT(usb->index), cvmx_usbcx_hprt_t, | ||
965 | prtena, ==, 1, 100000)) | ||
966 | { | ||
967 | if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO)) | ||
968 | cvmx_dprintf("%s: Timeout waiting for the port to finish reset\n", | ||
969 | __FUNCTION__); | ||
970 | CVMX_USB_RETURN(CVMX_USB_TIMEOUT); | ||
971 | } | ||
972 | |||
973 | /* Read the port speed field to get the enumerated speed, USBC_HPRT[PRTSPD]. */ | ||
974 | usb->usbcx_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index)); | ||
975 | if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO)) | ||
976 | cvmx_dprintf("%s: USB%d is in %s speed mode\n", __FUNCTION__, usb->index, | ||
977 | (usb->usbcx_hprt.s.prtspd == CVMX_USB_SPEED_HIGH) ? "high" : | ||
978 | (usb->usbcx_hprt.s.prtspd == CVMX_USB_SPEED_FULL) ? "full" : | ||
979 | "low"); | ||
980 | |||
981 | usbcx_ghwcfg3.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GHWCFG3(usb->index)); | ||
982 | |||
983 | /* 13. Program the USBC_GRXFSIZ register to select the size of the receive | ||
984 | FIFO (25%). */ | ||
985 | USB_SET_FIELD32(CVMX_USBCX_GRXFSIZ(usb->index), cvmx_usbcx_grxfsiz_t, | ||
986 | rxfdep, usbcx_ghwcfg3.s.dfifodepth / 4); | ||
987 | /* 14. Program the USBC_GNPTXFSIZ register to select the size and the | ||
988 | start address of the non- periodic transmit FIFO for nonperiodic | ||
989 | transactions (50%). */ | ||
990 | { | ||
991 | cvmx_usbcx_gnptxfsiz_t siz; | ||
992 | siz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GNPTXFSIZ(usb->index)); | ||
993 | siz.s.nptxfdep = usbcx_ghwcfg3.s.dfifodepth / 2; | ||
994 | siz.s.nptxfstaddr = usbcx_ghwcfg3.s.dfifodepth / 4; | ||
995 | __cvmx_usb_write_csr32(usb, CVMX_USBCX_GNPTXFSIZ(usb->index), siz.u32); | ||
996 | } | ||
997 | /* 15. Program the USBC_HPTXFSIZ register to select the size and start | ||
998 | address of the periodic transmit FIFO for periodic transactions (25%). */ | ||
999 | { | ||
1000 | cvmx_usbcx_hptxfsiz_t siz; | ||
1001 | siz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPTXFSIZ(usb->index)); | ||
1002 | siz.s.ptxfsize = usbcx_ghwcfg3.s.dfifodepth / 4; | ||
1003 | siz.s.ptxfstaddr = 3 * usbcx_ghwcfg3.s.dfifodepth / 4; | ||
1004 | __cvmx_usb_write_csr32(usb, CVMX_USBCX_HPTXFSIZ(usb->index), siz.u32); | ||
1005 | } | ||
1006 | /* Flush all FIFOs */ | ||
1007 | USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), cvmx_usbcx_grstctl_t, txfnum, 0x10); | ||
1008 | USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), cvmx_usbcx_grstctl_t, txfflsh, 1); | ||
1009 | CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), cvmx_usbcx_grstctl_t, | ||
1010 | txfflsh, ==, 0, 100); | ||
1011 | USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), cvmx_usbcx_grstctl_t, rxfflsh, 1); | ||
1012 | CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), cvmx_usbcx_grstctl_t, | ||
1013 | rxfflsh, ==, 0, 100); | ||
1014 | |||
1015 | CVMX_USB_RETURN(CVMX_USB_SUCCESS); | ||
1016 | } | ||
1017 | |||
1018 | |||
1019 | /** | ||
1020 | * Disable a USB port. After this call the USB port will not | ||
1021 | * generate data transfers and will not generate events. | ||
1022 | * Transactions in process will fail and call their | ||
1023 | * associated callbacks. | ||
1024 | * | ||
1025 | * @param state USB device state populated by | ||
1026 | * cvmx_usb_initialize(). | ||
1027 | * | ||
1028 | * @return CVMX_USB_SUCCESS or a negative error code defined in | ||
1029 | * cvmx_usb_status_t. | ||
1030 | */ | ||
1031 | cvmx_usb_status_t cvmx_usb_disable(cvmx_usb_state_t *state) | ||
1032 | { | ||
1033 | cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state; | ||
1034 | |||
1035 | CVMX_USB_LOG_CALLED(); | ||
1036 | CVMX_USB_LOG_PARAM("%p", state); | ||
1037 | |||
1038 | /* Disable the port */ | ||
1039 | USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), cvmx_usbcx_hprt_t, prtena, 1); | ||
1040 | CVMX_USB_RETURN(CVMX_USB_SUCCESS); | ||
1041 | } | ||
1042 | |||
1043 | |||
1044 | /** | ||
1045 | * Get the current state of the USB port. Use this call to | ||
1046 | * determine if the usb port has anything connected, is enabled, | ||
1047 | * or has some sort of error condition. The return value of this | ||
1048 | * call has "changed" bits to signal of the value of some fields | ||
1049 | * have changed between calls. These "changed" fields are based | ||
1050 | * on the last call to cvmx_usb_set_status(). In order to clear | ||
1051 | * them, you must update the status through cvmx_usb_set_status(). | ||
1052 | * | ||
1053 | * @param state USB device state populated by | ||
1054 | * cvmx_usb_initialize(). | ||
1055 | * | ||
1056 | * @return Port status information | ||
1057 | */ | ||
1058 | cvmx_usb_port_status_t cvmx_usb_get_status(cvmx_usb_state_t *state) | ||
1059 | { | ||
1060 | cvmx_usbcx_hprt_t usbc_hprt; | ||
1061 | cvmx_usb_port_status_t result; | ||
1062 | cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state; | ||
1063 | |||
1064 | memset(&result, 0, sizeof(result)); | ||
1065 | |||
1066 | CVMX_USB_LOG_CALLED(); | ||
1067 | CVMX_USB_LOG_PARAM("%p", state); | ||
1068 | |||
1069 | usbc_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index)); | ||
1070 | result.port_enabled = usbc_hprt.s.prtena; | ||
1071 | result.port_over_current = usbc_hprt.s.prtovrcurract; | ||
1072 | result.port_powered = usbc_hprt.s.prtpwr; | ||
1073 | result.port_speed = usbc_hprt.s.prtspd; | ||
1074 | result.connected = usbc_hprt.s.prtconnsts; | ||
1075 | result.connect_change = (result.connected != usb->port_status.connected); | ||
1076 | |||
1077 | if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CALLS)) | ||
1078 | cvmx_dprintf("%*s%s: returned port enabled=%d, over_current=%d, powered=%d, speed=%d, connected=%d, connect_change=%d\n", | ||
1079 | 2*(--usb->indent), "", __FUNCTION__, | ||
1080 | result.port_enabled, | ||
1081 | result.port_over_current, | ||
1082 | result.port_powered, | ||
1083 | result.port_speed, | ||
1084 | result.connected, | ||
1085 | result.connect_change); | ||
1086 | return result; | ||
1087 | } | ||
1088 | |||
1089 | |||
1090 | /** | ||
1091 | * Set the current state of the USB port. The status is used as | ||
1092 | * a reference for the "changed" bits returned by | ||
1093 | * cvmx_usb_get_status(). Other than serving as a reference, the | ||
1094 | * status passed to this function is not used. No fields can be | ||
1095 | * changed through this call. | ||
1096 | * | ||
1097 | * @param state USB device state populated by | ||
1098 | * cvmx_usb_initialize(). | ||
1099 | * @param port_status | ||
1100 | * Port status to set, most like returned by cvmx_usb_get_status() | ||
1101 | */ | ||
1102 | void cvmx_usb_set_status(cvmx_usb_state_t *state, cvmx_usb_port_status_t port_status) | ||
1103 | { | ||
1104 | cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state; | ||
1105 | CVMX_USB_LOG_CALLED(); | ||
1106 | CVMX_USB_LOG_PARAM("%p", state); | ||
1107 | usb->port_status = port_status; | ||
1108 | CVMX_USB_RETURN_NOTHING(); | ||
1109 | } | ||
1110 | |||
1111 | |||
1112 | /** | ||
1113 | * @INTERNAL | ||
1114 | * Convert a USB transaction into a handle | ||
1115 | * | ||
1116 | * @param usb USB device state populated by | ||
1117 | * cvmx_usb_initialize(). | ||
1118 | * @param transaction | ||
1119 | * Transaction to get handle for | ||
1120 | * | ||
1121 | * @return Handle | ||
1122 | */ | ||
1123 | static inline int __cvmx_usb_get_submit_handle(cvmx_usb_internal_state_t *usb, | ||
1124 | cvmx_usb_transaction_t *transaction) | ||
1125 | { | ||
1126 | return ((unsigned long)transaction - (unsigned long)usb->transaction) / | ||
1127 | sizeof(*transaction); | ||
1128 | } | ||
1129 | |||
1130 | |||
1131 | /** | ||
1132 | * @INTERNAL | ||
1133 | * Convert a USB pipe into a handle | ||
1134 | * | ||
1135 | * @param usb USB device state populated by | ||
1136 | * cvmx_usb_initialize(). | ||
1137 | * @param pipe Pipe to get handle for | ||
1138 | * | ||
1139 | * @return Handle | ||
1140 | */ | ||
1141 | static inline int __cvmx_usb_get_pipe_handle(cvmx_usb_internal_state_t *usb, | ||
1142 | cvmx_usb_pipe_t *pipe) | ||
1143 | { | ||
1144 | return ((unsigned long)pipe - (unsigned long)usb->pipe) / sizeof(*pipe); | ||
1145 | } | ||
1146 | |||
1147 | |||
1148 | /** | ||
1149 | * Open a virtual pipe between the host and a USB device. A pipe | ||
1150 | * must be opened before data can be transferred between a device | ||
1151 | * and Octeon. | ||
1152 | * | ||
1153 | * @param state USB device state populated by | ||
1154 | * cvmx_usb_initialize(). | ||
1155 | * @param flags Optional pipe flags defined in | ||
1156 | * cvmx_usb_pipe_flags_t. | ||
1157 | * @param device_addr | ||
1158 | * USB device address to open the pipe to | ||
1159 | * (0-127). | ||
1160 | * @param endpoint_num | ||
1161 | * USB endpoint number to open the pipe to | ||
1162 | * (0-15). | ||
1163 | * @param device_speed | ||
1164 | * The speed of the device the pipe is going | ||
1165 | * to. This must match the device's speed, | ||
1166 | * which may be different than the port speed. | ||
1167 | * @param max_packet The maximum packet length the device can | ||
1168 | * transmit/receive (low speed=0-8, full | ||
1169 | * speed=0-1023, high speed=0-1024). This value | ||
1170 | * comes from the standard endpoint descriptor | ||
1171 | * field wMaxPacketSize bits <10:0>. | ||
1172 | * @param transfer_type | ||
1173 | * The type of transfer this pipe is for. | ||
1174 | * @param transfer_dir | ||
1175 | * The direction the pipe is in. This is not | ||
1176 | * used for control pipes. | ||
1177 | * @param interval For ISOCHRONOUS and INTERRUPT transfers, | ||
1178 | * this is how often the transfer is scheduled | ||
1179 | * for. All other transfers should specify | ||
1180 | * zero. The units are in frames (8000/sec at | ||
1181 | * high speed, 1000/sec for full speed). | ||
1182 | * @param multi_count | ||
1183 | * For high speed devices, this is the maximum | ||
1184 | * allowed number of packet per microframe. | ||
1185 | * Specify zero for non high speed devices. This | ||
1186 | * value comes from the standard endpoint descriptor | ||
1187 | * field wMaxPacketSize bits <12:11>. | ||
1188 | * @param hub_device_addr | ||
1189 | * Hub device address this device is connected | ||
1190 | * to. Devices connected directly to Octeon | ||
1191 | * use zero. This is only used when the device | ||
1192 | * is full/low speed behind a high speed hub. | ||
1193 | * The address will be of the high speed hub, | ||
1194 | * not and full speed hubs after it. | ||
1195 | * @param hub_port Which port on the hub the device is | ||
1196 | * connected. Use zero for devices connected | ||
1197 | * directly to Octeon. Like hub_device_addr, | ||
1198 | * this is only used for full/low speed | ||
1199 | * devices behind a high speed hub. | ||
1200 | * | ||
1201 | * @return A non negative value is a pipe handle. Negative | ||
1202 | * values are failure codes from cvmx_usb_status_t. | ||
1203 | */ | ||
1204 | int cvmx_usb_open_pipe(cvmx_usb_state_t *state, cvmx_usb_pipe_flags_t flags, | ||
1205 | int device_addr, int endpoint_num, | ||
1206 | cvmx_usb_speed_t device_speed, int max_packet, | ||
1207 | cvmx_usb_transfer_t transfer_type, | ||
1208 | cvmx_usb_direction_t transfer_dir, int interval, | ||
1209 | int multi_count, int hub_device_addr, int hub_port) | ||
1210 | { | ||
1211 | cvmx_usb_pipe_t *pipe; | ||
1212 | cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state; | ||
1213 | |||
1214 | CVMX_USB_LOG_CALLED(); | ||
1215 | CVMX_USB_LOG_PARAM("%p", state); | ||
1216 | CVMX_USB_LOG_PARAM("0x%x", flags); | ||
1217 | CVMX_USB_LOG_PARAM("%d", device_addr); | ||
1218 | CVMX_USB_LOG_PARAM("%d", endpoint_num); | ||
1219 | CVMX_USB_LOG_PARAM("%d", device_speed); | ||
1220 | CVMX_USB_LOG_PARAM("%d", max_packet); | ||
1221 | CVMX_USB_LOG_PARAM("%d", transfer_type); | ||
1222 | CVMX_USB_LOG_PARAM("%d", transfer_dir); | ||
1223 | CVMX_USB_LOG_PARAM("%d", interval); | ||
1224 | CVMX_USB_LOG_PARAM("%d", multi_count); | ||
1225 | CVMX_USB_LOG_PARAM("%d", hub_device_addr); | ||
1226 | CVMX_USB_LOG_PARAM("%d", hub_port); | ||
1227 | |||
1228 | if (cvmx_unlikely((device_addr < 0) || (device_addr > MAX_USB_ADDRESS))) | ||
1229 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
1230 | if (cvmx_unlikely((endpoint_num < 0) || (endpoint_num > MAX_USB_ENDPOINT))) | ||
1231 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
1232 | if (cvmx_unlikely(device_speed > CVMX_USB_SPEED_LOW)) | ||
1233 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
1234 | if (cvmx_unlikely((max_packet <= 0) || (max_packet > 1024))) | ||
1235 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
1236 | if (cvmx_unlikely(transfer_type > CVMX_USB_TRANSFER_INTERRUPT)) | ||
1237 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
1238 | if (cvmx_unlikely((transfer_dir != CVMX_USB_DIRECTION_OUT) && | ||
1239 | (transfer_dir != CVMX_USB_DIRECTION_IN))) | ||
1240 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
1241 | if (cvmx_unlikely(interval < 0)) | ||
1242 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
1243 | if (cvmx_unlikely((transfer_type == CVMX_USB_TRANSFER_CONTROL) && interval)) | ||
1244 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
1245 | if (cvmx_unlikely(multi_count < 0)) | ||
1246 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
1247 | if (cvmx_unlikely((device_speed != CVMX_USB_SPEED_HIGH) && | ||
1248 | (multi_count != 0))) | ||
1249 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
1250 | if (cvmx_unlikely((hub_device_addr < 0) || (hub_device_addr > MAX_USB_ADDRESS))) | ||
1251 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
1252 | if (cvmx_unlikely((hub_port < 0) || (hub_port > MAX_USB_HUB_PORT))) | ||
1253 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
1254 | |||
1255 | /* Find a free pipe */ | ||
1256 | pipe = usb->free_pipes.head; | ||
1257 | if (!pipe) | ||
1258 | CVMX_USB_RETURN(CVMX_USB_NO_MEMORY); | ||
1259 | __cvmx_usb_remove_pipe(&usb->free_pipes, pipe); | ||
1260 | pipe->flags = flags | __CVMX_USB_PIPE_FLAGS_OPEN; | ||
1261 | if ((device_speed == CVMX_USB_SPEED_HIGH) && | ||
1262 | (transfer_dir == CVMX_USB_DIRECTION_OUT) && | ||
1263 | (transfer_type == CVMX_USB_TRANSFER_BULK)) | ||
1264 | pipe->flags |= __CVMX_USB_PIPE_FLAGS_NEED_PING; | ||
1265 | pipe->device_addr = device_addr; | ||
1266 | pipe->endpoint_num = endpoint_num; | ||
1267 | pipe->device_speed = device_speed; | ||
1268 | pipe->max_packet = max_packet; | ||
1269 | pipe->transfer_type = transfer_type; | ||
1270 | pipe->transfer_dir = transfer_dir; | ||
1271 | /* All pipes use interval to rate limit NAK processing. Force an interval | ||
1272 | if one wasn't supplied */ | ||
1273 | if (!interval) | ||
1274 | interval = 1; | ||
1275 | if (__cvmx_usb_pipe_needs_split(usb, pipe)) | ||
1276 | { | ||
1277 | pipe->interval = interval*8; | ||
1278 | /* Force start splits to be schedule on uFrame 0 */ | ||
1279 | pipe->next_tx_frame = ((usb->frame_number+7)&~7) + pipe->interval; | ||
1280 | } | ||
1281 | else | ||
1282 | { | ||
1283 | pipe->interval = interval; | ||
1284 | pipe->next_tx_frame = usb->frame_number + pipe->interval; | ||
1285 | } | ||
1286 | pipe->multi_count = multi_count; | ||
1287 | pipe->hub_device_addr = hub_device_addr; | ||
1288 | pipe->hub_port = hub_port; | ||
1289 | pipe->pid_toggle = 0; | ||
1290 | pipe->split_sc_frame = -1; | ||
1291 | __cvmx_usb_append_pipe(&usb->idle_pipes, pipe); | ||
1292 | |||
1293 | /* We don't need to tell the hardware about this pipe yet since | ||
1294 | it doesn't have any submitted requests */ | ||
1295 | |||
1296 | CVMX_USB_RETURN(__cvmx_usb_get_pipe_handle(usb, pipe)); | ||
1297 | } | ||
1298 | |||
1299 | |||
1300 | /** | ||
1301 | * @INTERNAL | ||
1302 | * Poll the RX FIFOs and remove data as needed. This function is only used | ||
1303 | * in non DMA mode. It is very important that this function be called quickly | ||
1304 | * enough to prevent FIFO overflow. | ||
1305 | * | ||
1306 | * @param usb USB device state populated by | ||
1307 | * cvmx_usb_initialize(). | ||
1308 | */ | ||
1309 | static void __cvmx_usb_poll_rx_fifo(cvmx_usb_internal_state_t *usb) | ||
1310 | { | ||
1311 | cvmx_usbcx_grxstsph_t rx_status; | ||
1312 | int channel; | ||
1313 | int bytes; | ||
1314 | uint64_t address; | ||
1315 | uint32_t *ptr; | ||
1316 | |||
1317 | CVMX_USB_LOG_CALLED(); | ||
1318 | CVMX_USB_LOG_PARAM("%p", usb); | ||
1319 | |||
1320 | rx_status.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GRXSTSPH(usb->index)); | ||
1321 | /* Only read data if IN data is there */ | ||
1322 | if (rx_status.s.pktsts != 2) | ||
1323 | CVMX_USB_RETURN_NOTHING(); | ||
1324 | /* Check if no data is available */ | ||
1325 | if (!rx_status.s.bcnt) | ||
1326 | CVMX_USB_RETURN_NOTHING(); | ||
1327 | |||
1328 | channel = rx_status.s.chnum; | ||
1329 | bytes = rx_status.s.bcnt; | ||
1330 | if (!bytes) | ||
1331 | CVMX_USB_RETURN_NOTHING(); | ||
1332 | |||
1333 | /* Get where the DMA engine would have written this data */ | ||
1334 | address = __cvmx_usb_read_csr64(usb, CVMX_USBNX_DMA0_INB_CHN0(usb->index) + channel*8); | ||
1335 | ptr = cvmx_phys_to_ptr(address); | ||
1336 | __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_INB_CHN0(usb->index) + channel*8, address + bytes); | ||
1337 | |||
1338 | /* Loop writing the FIFO data for this packet into memory */ | ||
1339 | while (bytes > 0) | ||
1340 | { | ||
1341 | *ptr++ = __cvmx_usb_read_csr32(usb, USB_FIFO_ADDRESS(channel, usb->index)); | ||
1342 | bytes -= 4; | ||
1343 | } | ||
1344 | CVMX_SYNCW; | ||
1345 | |||
1346 | CVMX_USB_RETURN_NOTHING(); | ||
1347 | } | ||
1348 | |||
1349 | |||
1350 | /** | ||
1351 | * Fill the TX hardware fifo with data out of the software | ||
1352 | * fifos | ||
1353 | * | ||
1354 | * @param usb USB device state populated by | ||
1355 | * cvmx_usb_initialize(). | ||
1356 | * @param fifo Software fifo to use | ||
1357 | * @param available Amount of space in the hardware fifo | ||
1358 | * | ||
1359 | * @return Non zero if the hardware fifo was too small and needs | ||
1360 | * to be serviced again. | ||
1361 | */ | ||
1362 | static int __cvmx_usb_fill_tx_hw(cvmx_usb_internal_state_t *usb, cvmx_usb_tx_fifo_t *fifo, int available) | ||
1363 | { | ||
1364 | CVMX_USB_LOG_CALLED(); | ||
1365 | CVMX_USB_LOG_PARAM("%p", usb); | ||
1366 | CVMX_USB_LOG_PARAM("%p", fifo); | ||
1367 | CVMX_USB_LOG_PARAM("%d", available); | ||
1368 | |||
1369 | /* We're done either when there isn't anymore space or the software FIFO | ||
1370 | is empty */ | ||
1371 | while (available && (fifo->head != fifo->tail)) | ||
1372 | { | ||
1373 | int i = fifo->tail; | ||
1374 | const uint32_t *ptr = cvmx_phys_to_ptr(fifo->entry[i].address); | ||
1375 | uint64_t csr_address = USB_FIFO_ADDRESS(fifo->entry[i].channel, usb->index) ^ 4; | ||
1376 | int words = available; | ||
1377 | |||
1378 | /* Limit the amount of data to waht the SW fifo has */ | ||
1379 | if (fifo->entry[i].size <= available) | ||
1380 | { | ||
1381 | words = fifo->entry[i].size; | ||
1382 | fifo->tail++; | ||
1383 | if (fifo->tail > MAX_CHANNELS) | ||
1384 | fifo->tail = 0; | ||
1385 | } | ||
1386 | |||
1387 | /* Update the next locations and counts */ | ||
1388 | available -= words; | ||
1389 | fifo->entry[i].address += words * 4; | ||
1390 | fifo->entry[i].size -= words; | ||
1391 | |||
1392 | /* Write the HW fifo data. The read every three writes is due | ||
1393 | to an errata on CN3XXX chips */ | ||
1394 | while (words > 3) | ||
1395 | { | ||
1396 | cvmx_write64_uint32(csr_address, *ptr++); | ||
1397 | cvmx_write64_uint32(csr_address, *ptr++); | ||
1398 | cvmx_write64_uint32(csr_address, *ptr++); | ||
1399 | cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index)); | ||
1400 | words -= 3; | ||
1401 | } | ||
1402 | cvmx_write64_uint32(csr_address, *ptr++); | ||
1403 | if (--words) | ||
1404 | { | ||
1405 | cvmx_write64_uint32(csr_address, *ptr++); | ||
1406 | if (--words) | ||
1407 | cvmx_write64_uint32(csr_address, *ptr++); | ||
1408 | } | ||
1409 | cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index)); | ||
1410 | } | ||
1411 | CVMX_USB_RETURN(fifo->head != fifo->tail); | ||
1412 | } | ||
1413 | |||
1414 | |||
1415 | /** | ||
1416 | * Check the hardware FIFOs and fill them as needed | ||
1417 | * | ||
1418 | * @param usb USB device state populated by | ||
1419 | * cvmx_usb_initialize(). | ||
1420 | */ | ||
1421 | static void __cvmx_usb_poll_tx_fifo(cvmx_usb_internal_state_t *usb) | ||
1422 | { | ||
1423 | CVMX_USB_LOG_CALLED(); | ||
1424 | CVMX_USB_LOG_PARAM("%p", usb); | ||
1425 | |||
1426 | if (usb->periodic.head != usb->periodic.tail) | ||
1427 | { | ||
1428 | cvmx_usbcx_hptxsts_t tx_status; | ||
1429 | tx_status.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPTXSTS(usb->index)); | ||
1430 | if (__cvmx_usb_fill_tx_hw(usb, &usb->periodic, tx_status.s.ptxfspcavail)) | ||
1431 | USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), cvmx_usbcx_gintmsk_t, ptxfempmsk, 1); | ||
1432 | else | ||
1433 | USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), cvmx_usbcx_gintmsk_t, ptxfempmsk, 0); | ||
1434 | } | ||
1435 | |||
1436 | if (usb->nonperiodic.head != usb->nonperiodic.tail) | ||
1437 | { | ||
1438 | cvmx_usbcx_gnptxsts_t tx_status; | ||
1439 | tx_status.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GNPTXSTS(usb->index)); | ||
1440 | if (__cvmx_usb_fill_tx_hw(usb, &usb->nonperiodic, tx_status.s.nptxfspcavail)) | ||
1441 | USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), cvmx_usbcx_gintmsk_t, nptxfempmsk, 1); | ||
1442 | else | ||
1443 | USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), cvmx_usbcx_gintmsk_t, nptxfempmsk, 0); | ||
1444 | } | ||
1445 | |||
1446 | CVMX_USB_RETURN_NOTHING(); | ||
1447 | } | ||
1448 | |||
1449 | |||
1450 | /** | ||
1451 | * @INTERNAL | ||
1452 | * Fill the TX FIFO with an outgoing packet | ||
1453 | * | ||
1454 | * @param usb USB device state populated by | ||
1455 | * cvmx_usb_initialize(). | ||
1456 | * @param channel Channel number to get packet from | ||
1457 | */ | ||
1458 | static void __cvmx_usb_fill_tx_fifo(cvmx_usb_internal_state_t *usb, int channel) | ||
1459 | { | ||
1460 | cvmx_usbcx_hccharx_t hcchar; | ||
1461 | cvmx_usbcx_hcspltx_t usbc_hcsplt; | ||
1462 | cvmx_usbcx_hctsizx_t usbc_hctsiz; | ||
1463 | cvmx_usb_tx_fifo_t *fifo; | ||
1464 | |||
1465 | CVMX_USB_LOG_CALLED(); | ||
1466 | CVMX_USB_LOG_PARAM("%p", usb); | ||
1467 | CVMX_USB_LOG_PARAM("%d", channel); | ||
1468 | |||
1469 | /* We only need to fill data on outbound channels */ | ||
1470 | hcchar.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index)); | ||
1471 | if (hcchar.s.epdir != CVMX_USB_DIRECTION_OUT) | ||
1472 | CVMX_USB_RETURN_NOTHING(); | ||
1473 | |||
1474 | /* OUT Splits only have data on the start and not the complete */ | ||
1475 | usbc_hcsplt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCSPLTX(channel, usb->index)); | ||
1476 | if (usbc_hcsplt.s.spltena && usbc_hcsplt.s.compsplt) | ||
1477 | CVMX_USB_RETURN_NOTHING(); | ||
1478 | |||
1479 | /* Find out how many bytes we need to fill and convert it into 32bit words */ | ||
1480 | usbc_hctsiz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index)); | ||
1481 | if (!usbc_hctsiz.s.xfersize) | ||
1482 | CVMX_USB_RETURN_NOTHING(); | ||
1483 | |||
1484 | if ((hcchar.s.eptype == CVMX_USB_TRANSFER_INTERRUPT) || | ||
1485 | (hcchar.s.eptype == CVMX_USB_TRANSFER_ISOCHRONOUS)) | ||
1486 | fifo = &usb->periodic; | ||
1487 | else | ||
1488 | fifo = &usb->nonperiodic; | ||
1489 | |||
1490 | fifo->entry[fifo->head].channel = channel; | ||
1491 | fifo->entry[fifo->head].address = __cvmx_usb_read_csr64(usb, CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8); | ||
1492 | fifo->entry[fifo->head].size = (usbc_hctsiz.s.xfersize+3)>>2; | ||
1493 | fifo->head++; | ||
1494 | if (fifo->head > MAX_CHANNELS) | ||
1495 | fifo->head = 0; | ||
1496 | |||
1497 | __cvmx_usb_poll_tx_fifo(usb); | ||
1498 | |||
1499 | CVMX_USB_RETURN_NOTHING(); | ||
1500 | } | ||
1501 | |||
1502 | /** | ||
1503 | * @INTERNAL | ||
1504 | * Perform channel specific setup for Control transactions. All | ||
1505 | * the generic stuff will already have been done in | ||
1506 | * __cvmx_usb_start_channel() | ||
1507 | * | ||
1508 | * @param usb USB device state populated by | ||
1509 | * cvmx_usb_initialize(). | ||
1510 | * @param channel Channel to setup | ||
1511 | * @param pipe Pipe for control transaction | ||
1512 | */ | ||
1513 | static void __cvmx_usb_start_channel_control(cvmx_usb_internal_state_t *usb, | ||
1514 | int channel, | ||
1515 | cvmx_usb_pipe_t *pipe) | ||
1516 | { | ||
1517 | cvmx_usb_transaction_t *transaction = pipe->head; | ||
1518 | cvmx_usb_control_header_t *header = cvmx_phys_to_ptr(transaction->control_header); | ||
1519 | int bytes_to_transfer = transaction->buffer_length - transaction->actual_bytes; | ||
1520 | int packets_to_transfer; | ||
1521 | cvmx_usbcx_hctsizx_t usbc_hctsiz; | ||
1522 | |||
1523 | CVMX_USB_LOG_CALLED(); | ||
1524 | CVMX_USB_LOG_PARAM("%p", usb); | ||
1525 | CVMX_USB_LOG_PARAM("%d", channel); | ||
1526 | CVMX_USB_LOG_PARAM("%p", pipe); | ||
1527 | |||
1528 | usbc_hctsiz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index)); | ||
1529 | |||
1530 | switch (transaction->stage) | ||
1531 | { | ||
1532 | case CVMX_USB_STAGE_NON_CONTROL: | ||
1533 | case CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE: | ||
1534 | cvmx_dprintf("%s: ERROR - Non control stage\n", __FUNCTION__); | ||
1535 | break; | ||
1536 | case CVMX_USB_STAGE_SETUP: | ||
1537 | usbc_hctsiz.s.pid = 3; /* Setup */ | ||
1538 | bytes_to_transfer = sizeof(*header); | ||
1539 | /* All Control operations start with a setup going OUT */ | ||
1540 | USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), cvmx_usbcx_hccharx_t, epdir, CVMX_USB_DIRECTION_OUT); | ||
1541 | /* Setup send the control header instead of the buffer data. The | ||
1542 | buffer data will be used in the next stage */ | ||
1543 | __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8, transaction->control_header); | ||
1544 | break; | ||
1545 | case CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE: | ||
1546 | usbc_hctsiz.s.pid = 3; /* Setup */ | ||
1547 | bytes_to_transfer = 0; | ||
1548 | /* All Control operations start with a setup going OUT */ | ||
1549 | USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), cvmx_usbcx_hccharx_t, epdir, CVMX_USB_DIRECTION_OUT); | ||
1550 | USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index), cvmx_usbcx_hcspltx_t, compsplt, 1); | ||
1551 | break; | ||
1552 | case CVMX_USB_STAGE_DATA: | ||
1553 | usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe); | ||
1554 | if (__cvmx_usb_pipe_needs_split(usb, pipe)) | ||
1555 | { | ||
1556 | if (header->s.request_type & 0x80) | ||
1557 | bytes_to_transfer = 0; | ||
1558 | else if (bytes_to_transfer > pipe->max_packet) | ||
1559 | bytes_to_transfer = pipe->max_packet; | ||
1560 | } | ||
1561 | USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), | ||
1562 | cvmx_usbcx_hccharx_t, epdir, | ||
1563 | ((header->s.request_type & 0x80) ? | ||
1564 | CVMX_USB_DIRECTION_IN : | ||
1565 | CVMX_USB_DIRECTION_OUT)); | ||
1566 | break; | ||
1567 | case CVMX_USB_STAGE_DATA_SPLIT_COMPLETE: | ||
1568 | usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe); | ||
1569 | if (!(header->s.request_type & 0x80)) | ||
1570 | bytes_to_transfer = 0; | ||
1571 | USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), | ||
1572 | cvmx_usbcx_hccharx_t, epdir, | ||
1573 | ((header->s.request_type & 0x80) ? | ||
1574 | CVMX_USB_DIRECTION_IN : | ||
1575 | CVMX_USB_DIRECTION_OUT)); | ||
1576 | USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index), cvmx_usbcx_hcspltx_t, compsplt, 1); | ||
1577 | break; | ||
1578 | case CVMX_USB_STAGE_STATUS: | ||
1579 | usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe); | ||
1580 | bytes_to_transfer = 0; | ||
1581 | USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), cvmx_usbcx_hccharx_t, epdir, | ||
1582 | ((header->s.request_type & 0x80) ? | ||
1583 | CVMX_USB_DIRECTION_OUT : | ||
1584 | CVMX_USB_DIRECTION_IN)); | ||
1585 | break; | ||
1586 | case CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE: | ||
1587 | usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe); | ||
1588 | bytes_to_transfer = 0; | ||
1589 | USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), cvmx_usbcx_hccharx_t, epdir, | ||
1590 | ((header->s.request_type & 0x80) ? | ||
1591 | CVMX_USB_DIRECTION_OUT : | ||
1592 | CVMX_USB_DIRECTION_IN)); | ||
1593 | USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index), cvmx_usbcx_hcspltx_t, compsplt, 1); | ||
1594 | break; | ||
1595 | } | ||
1596 | |||
1597 | /* Make sure the transfer never exceeds the byte limit of the hardware. | ||
1598 | Further bytes will be sent as continued transactions */ | ||
1599 | if (bytes_to_transfer > MAX_TRANSFER_BYTES) | ||
1600 | { | ||
1601 | /* Round MAX_TRANSFER_BYTES to a multiple of out packet size */ | ||
1602 | bytes_to_transfer = MAX_TRANSFER_BYTES / pipe->max_packet; | ||
1603 | bytes_to_transfer *= pipe->max_packet; | ||
1604 | } | ||
1605 | |||
1606 | /* Calculate the number of packets to transfer. If the length is zero | ||
1607 | we still need to transfer one packet */ | ||
1608 | packets_to_transfer = (bytes_to_transfer + pipe->max_packet - 1) / pipe->max_packet; | ||
1609 | if (packets_to_transfer == 0) | ||
1610 | packets_to_transfer = 1; | ||
1611 | else if ((packets_to_transfer>1) && (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)) | ||
1612 | { | ||
1613 | /* Limit to one packet when not using DMA. Channels must be restarted | ||
1614 | between every packet for IN transactions, so there is no reason to | ||
1615 | do multiple packets in a row */ | ||
1616 | packets_to_transfer = 1; | ||
1617 | bytes_to_transfer = packets_to_transfer * pipe->max_packet; | ||
1618 | } | ||
1619 | else if (packets_to_transfer > MAX_TRANSFER_PACKETS) | ||
1620 | { | ||
1621 | /* Limit the number of packet and data transferred to what the | ||
1622 | hardware can handle */ | ||
1623 | packets_to_transfer = MAX_TRANSFER_PACKETS; | ||
1624 | bytes_to_transfer = packets_to_transfer * pipe->max_packet; | ||
1625 | } | ||
1626 | |||
1627 | usbc_hctsiz.s.xfersize = bytes_to_transfer; | ||
1628 | usbc_hctsiz.s.pktcnt = packets_to_transfer; | ||
1629 | |||
1630 | __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index), usbc_hctsiz.u32); | ||
1631 | CVMX_USB_RETURN_NOTHING(); | ||
1632 | } | ||
1633 | |||
1634 | |||
1635 | /** | ||
1636 | * @INTERNAL | ||
1637 | * Start a channel to perform the pipe's head transaction | ||
1638 | * | ||
1639 | * @param usb USB device state populated by | ||
1640 | * cvmx_usb_initialize(). | ||
1641 | * @param channel Channel to setup | ||
1642 | * @param pipe Pipe to start | ||
1643 | */ | ||
1644 | static void __cvmx_usb_start_channel(cvmx_usb_internal_state_t *usb, | ||
1645 | int channel, | ||
1646 | cvmx_usb_pipe_t *pipe) | ||
1647 | { | ||
1648 | cvmx_usb_transaction_t *transaction = pipe->head; | ||
1649 | |||
1650 | CVMX_USB_LOG_CALLED(); | ||
1651 | CVMX_USB_LOG_PARAM("%p", usb); | ||
1652 | CVMX_USB_LOG_PARAM("%d", channel); | ||
1653 | CVMX_USB_LOG_PARAM("%p", pipe); | ||
1654 | |||
1655 | if (cvmx_unlikely((usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_TRANSFERS) || | ||
1656 | (pipe->flags & CVMX_USB_PIPE_FLAGS_DEBUG_TRANSFERS))) | ||
1657 | cvmx_dprintf("%s: Channel %d started. Pipe %d transaction %d stage %d\n", | ||
1658 | __FUNCTION__, channel, __cvmx_usb_get_pipe_handle(usb, pipe), | ||
1659 | __cvmx_usb_get_submit_handle(usb, transaction), | ||
1660 | transaction->stage); | ||
1661 | |||
1662 | /* Make sure all writes to the DMA region get flushed */ | ||
1663 | CVMX_SYNCW; | ||
1664 | |||
1665 | /* Attach the channel to the pipe */ | ||
1666 | usb->pipe_for_channel[channel] = pipe; | ||
1667 | pipe->channel = channel; | ||
1668 | pipe->flags |= __CVMX_USB_PIPE_FLAGS_SCHEDULED; | ||
1669 | |||
1670 | /* Mark this channel as in use */ | ||
1671 | usb->idle_hardware_channels &= ~(1<<channel); | ||
1672 | |||
1673 | /* Enable the channel interrupt bits */ | ||
1674 | { | ||
1675 | cvmx_usbcx_hcintx_t usbc_hcint; | ||
1676 | cvmx_usbcx_hcintmskx_t usbc_hcintmsk; | ||
1677 | cvmx_usbcx_haintmsk_t usbc_haintmsk; | ||
1678 | |||
1679 | /* Clear all channel status bits */ | ||
1680 | usbc_hcint.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCINTX(channel, usb->index)); | ||
1681 | __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTX(channel, usb->index), usbc_hcint.u32); | ||
1682 | |||
1683 | usbc_hcintmsk.u32 = 0; | ||
1684 | usbc_hcintmsk.s.chhltdmsk = 1; | ||
1685 | if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA) | ||
1686 | { | ||
1687 | /* Channels need these extra interrupts when we aren't in DMA mode */ | ||
1688 | usbc_hcintmsk.s.datatglerrmsk = 1; | ||
1689 | usbc_hcintmsk.s.frmovrunmsk = 1; | ||
1690 | usbc_hcintmsk.s.bblerrmsk = 1; | ||
1691 | usbc_hcintmsk.s.xacterrmsk = 1; | ||
1692 | if (__cvmx_usb_pipe_needs_split(usb, pipe)) | ||
1693 | { | ||
1694 | /* Splits don't generate xfercompl, so we need ACK and NYET */ | ||
1695 | usbc_hcintmsk.s.nyetmsk = 1; | ||
1696 | usbc_hcintmsk.s.ackmsk = 1; | ||
1697 | } | ||
1698 | usbc_hcintmsk.s.nakmsk = 1; | ||
1699 | usbc_hcintmsk.s.stallmsk = 1; | ||
1700 | usbc_hcintmsk.s.xfercomplmsk = 1; | ||
1701 | } | ||
1702 | __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), usbc_hcintmsk.u32); | ||
1703 | |||
1704 | /* Enable the channel interrupt to propagate */ | ||
1705 | usbc_haintmsk.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HAINTMSK(usb->index)); | ||
1706 | usbc_haintmsk.s.haintmsk |= 1<<channel; | ||
1707 | __cvmx_usb_write_csr32(usb, CVMX_USBCX_HAINTMSK(usb->index), usbc_haintmsk.u32); | ||
1708 | } | ||
1709 | |||
1710 | /* Setup the locations the DMA engines use */ | ||
1711 | { | ||
1712 | uint64_t dma_address = transaction->buffer + transaction->actual_bytes; | ||
1713 | if (transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS) | ||
1714 | dma_address = transaction->buffer + transaction->iso_packets[0].offset + transaction->actual_bytes; | ||
1715 | __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8, dma_address); | ||
1716 | __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_INB_CHN0(usb->index) + channel*8, dma_address); | ||
1717 | } | ||
1718 | |||
1719 | /* Setup both the size of the transfer and the SPLIT characteristics */ | ||
1720 | { | ||
1721 | cvmx_usbcx_hcspltx_t usbc_hcsplt = {.u32 = 0}; | ||
1722 | cvmx_usbcx_hctsizx_t usbc_hctsiz = {.u32 = 0}; | ||
1723 | int packets_to_transfer; | ||
1724 | int bytes_to_transfer = transaction->buffer_length - transaction->actual_bytes; | ||
1725 | |||
1726 | /* ISOCHRONOUS transactions store each individual transfer size in the | ||
1727 | packet structure, not the global buffer_length */ | ||
1728 | if (transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS) | ||
1729 | bytes_to_transfer = transaction->iso_packets[0].length - transaction->actual_bytes; | ||
1730 | |||
1731 | /* We need to do split transactions when we are talking to non high | ||
1732 | speed devices that are behind a high speed hub */ | ||
1733 | if (__cvmx_usb_pipe_needs_split(usb, pipe)) | ||
1734 | { | ||
1735 | /* On the start split phase (stage is even) record the frame number we | ||
1736 | will need to send the split complete. We only store the lower two bits | ||
1737 | since the time ahead can only be two frames */ | ||
1738 | if ((transaction->stage&1) == 0) | ||
1739 | { | ||
1740 | if (transaction->type == CVMX_USB_TRANSFER_BULK) | ||
1741 | pipe->split_sc_frame = (usb->frame_number + 1) & 0x7f; | ||
1742 | else | ||
1743 | pipe->split_sc_frame = (usb->frame_number + 2) & 0x7f; | ||
1744 | } | ||
1745 | else | ||
1746 | pipe->split_sc_frame = -1; | ||
1747 | |||
1748 | usbc_hcsplt.s.spltena = 1; | ||
1749 | usbc_hcsplt.s.hubaddr = pipe->hub_device_addr; | ||
1750 | usbc_hcsplt.s.prtaddr = pipe->hub_port; | ||
1751 | usbc_hcsplt.s.compsplt = (transaction->stage == CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE); | ||
1752 | |||
1753 | /* SPLIT transactions can only ever transmit one data packet so | ||
1754 | limit the transfer size to the max packet size */ | ||
1755 | if (bytes_to_transfer > pipe->max_packet) | ||
1756 | bytes_to_transfer = pipe->max_packet; | ||
1757 | |||
1758 | /* ISOCHRONOUS OUT splits are unique in that they limit | ||
1759 | data transfers to 188 byte chunks representing the | ||
1760 | begin/middle/end of the data or all */ | ||
1761 | if (!usbc_hcsplt.s.compsplt && | ||
1762 | (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) && | ||
1763 | (pipe->transfer_type == CVMX_USB_TRANSFER_ISOCHRONOUS)) | ||
1764 | { | ||
1765 | /* Clear the split complete frame number as there isn't going | ||
1766 | to be a split complete */ | ||
1767 | pipe->split_sc_frame = -1; | ||
1768 | /* See if we've started this transfer and sent data */ | ||
1769 | if (transaction->actual_bytes == 0) | ||
1770 | { | ||
1771 | /* Nothing sent yet, this is either a begin or the | ||
1772 | entire payload */ | ||
1773 | if (bytes_to_transfer <= 188) | ||
1774 | usbc_hcsplt.s.xactpos = 3; /* Entire payload in one go */ | ||
1775 | else | ||
1776 | usbc_hcsplt.s.xactpos = 2; /* First part of payload */ | ||
1777 | } | ||
1778 | else | ||
1779 | { | ||
1780 | /* Continuing the previous data, we must either be | ||
1781 | in the middle or at the end */ | ||
1782 | if (bytes_to_transfer <= 188) | ||
1783 | usbc_hcsplt.s.xactpos = 1; /* End of payload */ | ||
1784 | else | ||
1785 | usbc_hcsplt.s.xactpos = 0; /* Middle of payload */ | ||
1786 | } | ||
1787 | /* Again, the transfer size is limited to 188 bytes */ | ||
1788 | if (bytes_to_transfer > 188) | ||
1789 | bytes_to_transfer = 188; | ||
1790 | } | ||
1791 | } | ||
1792 | |||
1793 | /* Make sure the transfer never exceeds the byte limit of the hardware. | ||
1794 | Further bytes will be sent as continued transactions */ | ||
1795 | if (bytes_to_transfer > MAX_TRANSFER_BYTES) | ||
1796 | { | ||
1797 | /* Round MAX_TRANSFER_BYTES to a multiple of out packet size */ | ||
1798 | bytes_to_transfer = MAX_TRANSFER_BYTES / pipe->max_packet; | ||
1799 | bytes_to_transfer *= pipe->max_packet; | ||
1800 | } | ||
1801 | |||
1802 | /* Calculate the number of packets to transfer. If the length is zero | ||
1803 | we still need to transfer one packet */ | ||
1804 | packets_to_transfer = (bytes_to_transfer + pipe->max_packet - 1) / pipe->max_packet; | ||
1805 | if (packets_to_transfer == 0) | ||
1806 | packets_to_transfer = 1; | ||
1807 | else if ((packets_to_transfer>1) && (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)) | ||
1808 | { | ||
1809 | /* Limit to one packet when not using DMA. Channels must be restarted | ||
1810 | between every packet for IN transactions, so there is no reason to | ||
1811 | do multiple packets in a row */ | ||
1812 | packets_to_transfer = 1; | ||
1813 | bytes_to_transfer = packets_to_transfer * pipe->max_packet; | ||
1814 | } | ||
1815 | else if (packets_to_transfer > MAX_TRANSFER_PACKETS) | ||
1816 | { | ||
1817 | /* Limit the number of packet and data transferred to what the | ||
1818 | hardware can handle */ | ||
1819 | packets_to_transfer = MAX_TRANSFER_PACKETS; | ||
1820 | bytes_to_transfer = packets_to_transfer * pipe->max_packet; | ||
1821 | } | ||
1822 | |||
1823 | usbc_hctsiz.s.xfersize = bytes_to_transfer; | ||
1824 | usbc_hctsiz.s.pktcnt = packets_to_transfer; | ||
1825 | |||
1826 | /* Update the DATA0/DATA1 toggle */ | ||
1827 | usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe); | ||
1828 | /* High speed pipes may need a hardware ping before they start */ | ||
1829 | if (pipe->flags & __CVMX_USB_PIPE_FLAGS_NEED_PING) | ||
1830 | usbc_hctsiz.s.dopng = 1; | ||
1831 | |||
1832 | __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCSPLTX(channel, usb->index), usbc_hcsplt.u32); | ||
1833 | __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index), usbc_hctsiz.u32); | ||
1834 | } | ||
1835 | |||
1836 | /* Setup the Host Channel Characteristics Register */ | ||
1837 | { | ||
1838 | cvmx_usbcx_hccharx_t usbc_hcchar = {.u32 = 0}; | ||
1839 | |||
1840 | /* Set the startframe odd/even properly. This is only used for periodic */ | ||
1841 | usbc_hcchar.s.oddfrm = usb->frame_number&1; | ||
1842 | |||
1843 | /* Set the number of back to back packets allowed by this endpoint. | ||
1844 | Split transactions interpret "ec" as the number of immediate | ||
1845 | retries of failure. These retries happen too quickly, so we | ||
1846 | disable these entirely for splits */ | ||
1847 | if (__cvmx_usb_pipe_needs_split(usb, pipe)) | ||
1848 | usbc_hcchar.s.ec = 1; | ||
1849 | else if (pipe->multi_count < 1) | ||
1850 | usbc_hcchar.s.ec = 1; | ||
1851 | else if (pipe->multi_count > 3) | ||
1852 | usbc_hcchar.s.ec = 3; | ||
1853 | else | ||
1854 | usbc_hcchar.s.ec = pipe->multi_count; | ||
1855 | |||
1856 | /* Set the rest of the endpoint specific settings */ | ||
1857 | usbc_hcchar.s.devaddr = pipe->device_addr; | ||
1858 | usbc_hcchar.s.eptype = transaction->type; | ||
1859 | usbc_hcchar.s.lspddev = (pipe->device_speed == CVMX_USB_SPEED_LOW); | ||
1860 | usbc_hcchar.s.epdir = pipe->transfer_dir; | ||
1861 | usbc_hcchar.s.epnum = pipe->endpoint_num; | ||
1862 | usbc_hcchar.s.mps = pipe->max_packet; | ||
1863 | __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index), usbc_hcchar.u32); | ||
1864 | } | ||
1865 | |||
1866 | /* Do transaction type specific fixups as needed */ | ||
1867 | switch (transaction->type) | ||
1868 | { | ||
1869 | case CVMX_USB_TRANSFER_CONTROL: | ||
1870 | __cvmx_usb_start_channel_control(usb, channel, pipe); | ||
1871 | break; | ||
1872 | case CVMX_USB_TRANSFER_BULK: | ||
1873 | case CVMX_USB_TRANSFER_INTERRUPT: | ||
1874 | break; | ||
1875 | case CVMX_USB_TRANSFER_ISOCHRONOUS: | ||
1876 | if (!__cvmx_usb_pipe_needs_split(usb, pipe)) | ||
1877 | { | ||
1878 | /* ISO transactions require different PIDs depending on direction | ||
1879 | and how many packets are needed */ | ||
1880 | if (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) | ||
1881 | { | ||
1882 | if (pipe->multi_count < 2) /* Need DATA0 */ | ||
1883 | USB_SET_FIELD32(CVMX_USBCX_HCTSIZX(channel, usb->index), cvmx_usbcx_hctsizx_t, pid, 0); | ||
1884 | else /* Need MDATA */ | ||
1885 | USB_SET_FIELD32(CVMX_USBCX_HCTSIZX(channel, usb->index), cvmx_usbcx_hctsizx_t, pid, 3); | ||
1886 | } | ||
1887 | } | ||
1888 | break; | ||
1889 | } | ||
1890 | { | ||
1891 | cvmx_usbcx_hctsizx_t usbc_hctsiz = {.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index))}; | ||
1892 | transaction->xfersize = usbc_hctsiz.s.xfersize; | ||
1893 | transaction->pktcnt = usbc_hctsiz.s.pktcnt; | ||
1894 | } | ||
1895 | /* Remeber when we start a split transaction */ | ||
1896 | if (__cvmx_usb_pipe_needs_split(usb, pipe)) | ||
1897 | usb->active_split = transaction; | ||
1898 | USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), cvmx_usbcx_hccharx_t, chena, 1); | ||
1899 | if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA) | ||
1900 | __cvmx_usb_fill_tx_fifo(usb, channel); | ||
1901 | CVMX_USB_RETURN_NOTHING(); | ||
1902 | } | ||
1903 | |||
1904 | |||
1905 | /** | ||
1906 | * @INTERNAL | ||
1907 | * Find a pipe that is ready to be scheduled to hardware. | ||
1908 | * @param usb USB device state populated by | ||
1909 | * cvmx_usb_initialize(). | ||
1910 | * @param list Pipe list to search | ||
1911 | * @param current_frame | ||
1912 | * Frame counter to use as a time reference. | ||
1913 | * | ||
1914 | * @return Pipe or NULL if none are ready | ||
1915 | */ | ||
1916 | 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) | ||
1917 | { | ||
1918 | cvmx_usb_pipe_t *pipe = list->head; | ||
1919 | while (pipe) | ||
1920 | { | ||
1921 | if (!(pipe->flags & __CVMX_USB_PIPE_FLAGS_SCHEDULED) && pipe->head && | ||
1922 | (pipe->next_tx_frame <= current_frame) && | ||
1923 | ((pipe->split_sc_frame == -1) || ((((int)current_frame - (int)pipe->split_sc_frame) & 0x7f) < 0x40)) && | ||
1924 | (!usb->active_split || (usb->active_split == pipe->head))) | ||
1925 | { | ||
1926 | CVMX_PREFETCH(pipe, 128); | ||
1927 | CVMX_PREFETCH(pipe->head, 0); | ||
1928 | return pipe; | ||
1929 | } | ||
1930 | pipe = pipe->next; | ||
1931 | } | ||
1932 | return NULL; | ||
1933 | } | ||
1934 | |||
1935 | |||
1936 | /** | ||
1937 | * @INTERNAL | ||
1938 | * Called whenever a pipe might need to be scheduled to the | ||
1939 | * hardware. | ||
1940 | * | ||
1941 | * @param usb USB device state populated by | ||
1942 | * cvmx_usb_initialize(). | ||
1943 | * @param is_sof True if this schedule was called on a SOF interrupt. | ||
1944 | */ | ||
1945 | static void __cvmx_usb_schedule(cvmx_usb_internal_state_t *usb, int is_sof) | ||
1946 | { | ||
1947 | int channel; | ||
1948 | cvmx_usb_pipe_t *pipe; | ||
1949 | int need_sof; | ||
1950 | cvmx_usb_transfer_t ttype; | ||
1951 | |||
1952 | CVMX_USB_LOG_CALLED(); | ||
1953 | CVMX_USB_LOG_PARAM("%p", usb); | ||
1954 | |||
1955 | if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA) | ||
1956 | { | ||
1957 | /* Without DMA we need to be careful to not schedule something at the end of a frame and cause an overrun */ | ||
1958 | cvmx_usbcx_hfnum_t hfnum = {.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index))}; | ||
1959 | cvmx_usbcx_hfir_t hfir = {.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFIR(usb->index))}; | ||
1960 | if (hfnum.s.frrem < hfir.s.frint/4) | ||
1961 | goto done; | ||
1962 | } | ||
1963 | |||
1964 | while (usb->idle_hardware_channels) | ||
1965 | { | ||
1966 | /* Find an idle channel */ | ||
1967 | CVMX_CLZ(channel, usb->idle_hardware_channels); | ||
1968 | channel = 31 - channel; | ||
1969 | if (cvmx_unlikely(channel > 7)) | ||
1970 | { | ||
1971 | if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO)) | ||
1972 | cvmx_dprintf("%s: Idle hardware channels has a channel higher than 7. This is wrong\n", __FUNCTION__); | ||
1973 | break; | ||
1974 | } | ||
1975 | |||
1976 | /* Find a pipe needing service */ | ||
1977 | pipe = NULL; | ||
1978 | if (is_sof) | ||
1979 | { | ||
1980 | /* Only process periodic pipes on SOF interrupts. This way we are | ||
1981 | sure that the periodic data is sent in the beginning of the | ||
1982 | frame */ | ||
1983 | pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_ISOCHRONOUS, usb->frame_number); | ||
1984 | if (cvmx_likely(!pipe)) | ||
1985 | pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_INTERRUPT, usb->frame_number); | ||
1986 | } | ||
1987 | if (cvmx_likely(!pipe)) | ||
1988 | { | ||
1989 | pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_CONTROL, usb->frame_number); | ||
1990 | if (cvmx_likely(!pipe)) | ||
1991 | pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_BULK, usb->frame_number); | ||
1992 | } | ||
1993 | if (!pipe) | ||
1994 | break; | ||
1995 | |||
1996 | CVMX_USB_LOG_PARAM("%d", channel); | ||
1997 | CVMX_USB_LOG_PARAM("%p", pipe); | ||
1998 | |||
1999 | if (cvmx_unlikely((usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_TRANSFERS) || | ||
2000 | (pipe->flags & CVMX_USB_PIPE_FLAGS_DEBUG_TRANSFERS))) | ||
2001 | { | ||
2002 | cvmx_usb_transaction_t *transaction = pipe->head; | ||
2003 | const cvmx_usb_control_header_t *header = (transaction->control_header) ? cvmx_phys_to_ptr(transaction->control_header) : NULL; | ||
2004 | const char *dir = (pipe->transfer_dir == CVMX_USB_DIRECTION_IN) ? "IN" : "OUT"; | ||
2005 | const char *type; | ||
2006 | switch (pipe->transfer_type) | ||
2007 | { | ||
2008 | case CVMX_USB_TRANSFER_CONTROL: | ||
2009 | type = "SETUP"; | ||
2010 | dir = (header->s.request_type & 0x80) ? "IN" : "OUT"; | ||
2011 | break; | ||
2012 | case CVMX_USB_TRANSFER_ISOCHRONOUS: | ||
2013 | type = "ISOCHRONOUS"; | ||
2014 | break; | ||
2015 | case CVMX_USB_TRANSFER_BULK: | ||
2016 | type = "BULK"; | ||
2017 | break; | ||
2018 | default: /* CVMX_USB_TRANSFER_INTERRUPT */ | ||
2019 | type = "INTERRUPT"; | ||
2020 | break; | ||
2021 | } | ||
2022 | cvmx_dprintf("%s: Starting pipe %d, transaction %d on channel %d. %s %s len=%d header=0x%llx\n", | ||
2023 | __FUNCTION__, __cvmx_usb_get_pipe_handle(usb, pipe), | ||
2024 | __cvmx_usb_get_submit_handle(usb, transaction), | ||
2025 | channel, type, dir, | ||
2026 | transaction->buffer_length, | ||
2027 | (header) ? (unsigned long long)header->u64 : 0ull); | ||
2028 | } | ||
2029 | __cvmx_usb_start_channel(usb, channel, pipe); | ||
2030 | } | ||
2031 | |||
2032 | done: | ||
2033 | /* Only enable SOF interrupts when we have transactions pending in the | ||
2034 | future that might need to be scheduled */ | ||
2035 | need_sof = 0; | ||
2036 | for (ttype=CVMX_USB_TRANSFER_CONTROL; ttype<=CVMX_USB_TRANSFER_INTERRUPT; ttype++) | ||
2037 | { | ||
2038 | pipe = usb->active_pipes[ttype].head; | ||
2039 | while (pipe) | ||
2040 | { | ||
2041 | if (pipe->next_tx_frame > usb->frame_number) | ||
2042 | { | ||
2043 | need_sof = 1; | ||
2044 | break; | ||
2045 | } | ||
2046 | pipe=pipe->next; | ||
2047 | } | ||
2048 | } | ||
2049 | USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), cvmx_usbcx_gintmsk_t, sofmsk, need_sof); | ||
2050 | CVMX_USB_RETURN_NOTHING(); | ||
2051 | } | ||
2052 | |||
2053 | |||
2054 | /** | ||
2055 | * @INTERNAL | ||
2056 | * Call a user's callback for a specific reason. | ||
2057 | * | ||
2058 | * @param usb USB device state populated by | ||
2059 | * cvmx_usb_initialize(). | ||
2060 | * @param pipe Pipe the callback is for or NULL | ||
2061 | * @param transaction | ||
2062 | * Transaction the callback is for or NULL | ||
2063 | * @param reason Reason this callback is being called | ||
2064 | * @param complete_code | ||
2065 | * Completion code for the transaction, if any | ||
2066 | */ | ||
2067 | static void __cvmx_usb_perform_callback(cvmx_usb_internal_state_t *usb, | ||
2068 | cvmx_usb_pipe_t *pipe, | ||
2069 | cvmx_usb_transaction_t *transaction, | ||
2070 | cvmx_usb_callback_t reason, | ||
2071 | cvmx_usb_complete_t complete_code) | ||
2072 | { | ||
2073 | cvmx_usb_callback_func_t callback = usb->callback[reason]; | ||
2074 | void *user_data = usb->callback_data[reason]; | ||
2075 | int submit_handle = -1; | ||
2076 | int pipe_handle = -1; | ||
2077 | int bytes_transferred = 0; | ||
2078 | |||
2079 | if (pipe) | ||
2080 | pipe_handle = __cvmx_usb_get_pipe_handle(usb, pipe); | ||
2081 | |||
2082 | if (transaction) | ||
2083 | { | ||
2084 | submit_handle = __cvmx_usb_get_submit_handle(usb, transaction); | ||
2085 | bytes_transferred = transaction->actual_bytes; | ||
2086 | /* Transactions are allowed to override the default callback */ | ||
2087 | if ((reason == CVMX_USB_CALLBACK_TRANSFER_COMPLETE) && transaction->callback) | ||
2088 | { | ||
2089 | callback = transaction->callback; | ||
2090 | user_data = transaction->callback_data; | ||
2091 | } | ||
2092 | } | ||
2093 | |||
2094 | if (!callback) | ||
2095 | return; | ||
2096 | |||
2097 | if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CALLBACKS)) | ||
2098 | cvmx_dprintf("%*s%s: calling callback %p(usb=%p, complete_code=%s, " | ||
2099 | "pipe_handle=%d, submit_handle=%d, bytes_transferred=%d, user_data=%p);\n", | ||
2100 | 2*usb->indent, "", __FUNCTION__, callback, usb, | ||
2101 | __cvmx_usb_complete_to_string(complete_code), | ||
2102 | pipe_handle, submit_handle, bytes_transferred, user_data); | ||
2103 | |||
2104 | callback((cvmx_usb_state_t *)usb, reason, complete_code, pipe_handle, submit_handle, | ||
2105 | bytes_transferred, user_data); | ||
2106 | |||
2107 | if (cvmx_unlikely(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_CALLBACKS)) | ||
2108 | cvmx_dprintf("%*s%s: callback %p complete\n", 2*usb->indent, "", | ||
2109 | __FUNCTION__, callback); | ||
2110 | } | ||
2111 | |||
2112 | |||
2113 | /** | ||
2114 | * @INTERNAL | ||
2115 | * Signal the completion of a transaction and free it. The | ||
2116 | * transaction will be removed from the pipe transaction list. | ||
2117 | * | ||
2118 | * @param usb USB device state populated by | ||
2119 | * cvmx_usb_initialize(). | ||
2120 | * @param pipe Pipe the transaction is on | ||
2121 | * @param transaction | ||
2122 | * Transaction that completed | ||
2123 | * @param complete_code | ||
2124 | * Completion code | ||
2125 | */ | ||
2126 | static void __cvmx_usb_perform_complete(cvmx_usb_internal_state_t * usb, | ||
2127 | cvmx_usb_pipe_t *pipe, | ||
2128 | cvmx_usb_transaction_t *transaction, | ||
2129 | cvmx_usb_complete_t complete_code) | ||
2130 | { | ||
2131 | CVMX_USB_LOG_CALLED(); | ||
2132 | CVMX_USB_LOG_PARAM("%p", usb); | ||
2133 | CVMX_USB_LOG_PARAM("%p", pipe); | ||
2134 | CVMX_USB_LOG_PARAM("%p", transaction); | ||
2135 | CVMX_USB_LOG_PARAM("%d", complete_code); | ||
2136 | |||
2137 | /* If this was a split then clear our split in progress marker */ | ||
2138 | if (usb->active_split == transaction) | ||
2139 | usb->active_split = NULL; | ||
2140 | |||
2141 | /* Isochronous transactions need extra processing as they might not be done | ||
2142 | after a single data transfer */ | ||
2143 | if (cvmx_unlikely(transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS)) | ||
2144 | { | ||
2145 | /* Update the number of bytes transferred in this ISO packet */ | ||
2146 | transaction->iso_packets[0].length = transaction->actual_bytes; | ||
2147 | transaction->iso_packets[0].status = complete_code; | ||
2148 | |||
2149 | /* If there are more ISOs pending and we succeeded, schedule the next | ||
2150 | one */ | ||
2151 | if ((transaction->iso_number_packets > 1) && (complete_code == CVMX_USB_COMPLETE_SUCCESS)) | ||
2152 | { | ||
2153 | transaction->actual_bytes = 0; /* No bytes transferred for this packet as of yet */ | ||
2154 | transaction->iso_number_packets--; /* One less ISO waiting to transfer */ | ||
2155 | transaction->iso_packets++; /* Increment to the next location in our packet array */ | ||
2156 | transaction->stage = CVMX_USB_STAGE_NON_CONTROL; | ||
2157 | goto done; | ||
2158 | } | ||
2159 | } | ||
2160 | |||
2161 | /* Remove the transaction from the pipe list */ | ||
2162 | if (transaction->next) | ||
2163 | transaction->next->prev = transaction->prev; | ||
2164 | else | ||
2165 | pipe->tail = transaction->prev; | ||
2166 | if (transaction->prev) | ||
2167 | transaction->prev->next = transaction->next; | ||
2168 | else | ||
2169 | pipe->head = transaction->next; | ||
2170 | if (!pipe->head) | ||
2171 | { | ||
2172 | __cvmx_usb_remove_pipe(usb->active_pipes + pipe->transfer_type, pipe); | ||
2173 | __cvmx_usb_append_pipe(&usb->idle_pipes, pipe); | ||
2174 | |||
2175 | } | ||
2176 | __cvmx_usb_perform_callback(usb, pipe, transaction, | ||
2177 | CVMX_USB_CALLBACK_TRANSFER_COMPLETE, | ||
2178 | complete_code); | ||
2179 | __cvmx_usb_free_transaction(usb, transaction); | ||
2180 | done: | ||
2181 | CVMX_USB_RETURN_NOTHING(); | ||
2182 | } | ||
2183 | |||
2184 | |||
2185 | /** | ||
2186 | * @INTERNAL | ||
2187 | * Submit a usb transaction to a pipe. Called for all types | ||
2188 | * of transactions. | ||
2189 | * | ||
2190 | * @param usb | ||
2191 | * @param pipe_handle | ||
2192 | * Which pipe to submit to. Will be validated in this function. | ||
2193 | * @param type Transaction type | ||
2194 | * @param flags Flags for the transaction | ||
2195 | * @param buffer User buffer for the transaction | ||
2196 | * @param buffer_length | ||
2197 | * User buffer's length in bytes | ||
2198 | * @param control_header | ||
2199 | * For control transactions, the 8 byte standard header | ||
2200 | * @param iso_start_frame | ||
2201 | * For ISO transactions, the start frame | ||
2202 | * @param iso_number_packets | ||
2203 | * For ISO, the number of packet in the transaction. | ||
2204 | * @param iso_packets | ||
2205 | * A description of each ISO packet | ||
2206 | * @param callback User callback to call when the transaction completes | ||
2207 | * @param user_data User's data for the callback | ||
2208 | * | ||
2209 | * @return Submit handle or negative on failure. Matches the result | ||
2210 | * in the external API. | ||
2211 | */ | ||
2212 | static int __cvmx_usb_submit_transaction(cvmx_usb_internal_state_t *usb, | ||
2213 | int pipe_handle, | ||
2214 | cvmx_usb_transfer_t type, | ||
2215 | int flags, | ||
2216 | uint64_t buffer, | ||
2217 | int buffer_length, | ||
2218 | uint64_t control_header, | ||
2219 | int iso_start_frame, | ||
2220 | int iso_number_packets, | ||
2221 | cvmx_usb_iso_packet_t *iso_packets, | ||
2222 | cvmx_usb_callback_func_t callback, | ||
2223 | void *user_data) | ||
2224 | { | ||
2225 | int submit_handle; | ||
2226 | cvmx_usb_transaction_t *transaction; | ||
2227 | cvmx_usb_pipe_t *pipe = usb->pipe + pipe_handle; | ||
2228 | |||
2229 | CVMX_USB_LOG_CALLED(); | ||
2230 | if (cvmx_unlikely((pipe_handle < 0) || (pipe_handle >= MAX_PIPES))) | ||
2231 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2232 | /* Fail if the pipe isn't open */ | ||
2233 | if (cvmx_unlikely((pipe->flags & __CVMX_USB_PIPE_FLAGS_OPEN) == 0)) | ||
2234 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2235 | if (cvmx_unlikely(pipe->transfer_type != type)) | ||
2236 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2237 | |||
2238 | transaction = __cvmx_usb_alloc_transaction(usb); | ||
2239 | if (cvmx_unlikely(!transaction)) | ||
2240 | CVMX_USB_RETURN(CVMX_USB_NO_MEMORY); | ||
2241 | |||
2242 | transaction->type = type; | ||
2243 | transaction->flags |= flags; | ||
2244 | transaction->buffer = buffer; | ||
2245 | transaction->buffer_length = buffer_length; | ||
2246 | transaction->control_header = control_header; | ||
2247 | transaction->iso_start_frame = iso_start_frame; // FIXME: This is not used, implement it | ||
2248 | transaction->iso_number_packets = iso_number_packets; | ||
2249 | transaction->iso_packets = iso_packets; | ||
2250 | transaction->callback = callback; | ||
2251 | transaction->callback_data = user_data; | ||
2252 | if (transaction->type == CVMX_USB_TRANSFER_CONTROL) | ||
2253 | transaction->stage = CVMX_USB_STAGE_SETUP; | ||
2254 | else | ||
2255 | transaction->stage = CVMX_USB_STAGE_NON_CONTROL; | ||
2256 | |||
2257 | transaction->next = NULL; | ||
2258 | if (pipe->tail) | ||
2259 | { | ||
2260 | transaction->prev = pipe->tail; | ||
2261 | transaction->prev->next = transaction; | ||
2262 | } | ||
2263 | else | ||
2264 | { | ||
2265 | if (pipe->next_tx_frame < usb->frame_number) | ||
2266 | pipe->next_tx_frame = usb->frame_number + pipe->interval - | ||
2267 | (usb->frame_number - pipe->next_tx_frame) % pipe->interval; | ||
2268 | transaction->prev = NULL; | ||
2269 | pipe->head = transaction; | ||
2270 | __cvmx_usb_remove_pipe(&usb->idle_pipes, pipe); | ||
2271 | __cvmx_usb_append_pipe(usb->active_pipes + pipe->transfer_type, pipe); | ||
2272 | } | ||
2273 | pipe->tail = transaction; | ||
2274 | |||
2275 | submit_handle = __cvmx_usb_get_submit_handle(usb, transaction); | ||
2276 | |||
2277 | /* We may need to schedule the pipe if this was the head of the pipe */ | ||
2278 | if (!transaction->prev) | ||
2279 | __cvmx_usb_schedule(usb, 0); | ||
2280 | |||
2281 | CVMX_USB_RETURN(submit_handle); | ||
2282 | } | ||
2283 | |||
2284 | |||
2285 | /** | ||
2286 | * Call to submit a USB Bulk transfer to a pipe. | ||
2287 | * | ||
2288 | * @param state USB device state populated by | ||
2289 | * cvmx_usb_initialize(). | ||
2290 | * @param pipe_handle | ||
2291 | * Handle to the pipe for the transfer. | ||
2292 | * @param buffer Physical address of the data buffer in | ||
2293 | * memory. Note that this is NOT A POINTER, but | ||
2294 | * the full 64bit physical address of the | ||
2295 | * buffer. This may be zero if buffer_length is | ||
2296 | * zero. | ||
2297 | * @param buffer_length | ||
2298 | * Length of buffer in bytes. | ||
2299 | * @param callback Function to call when this transaction | ||
2300 | * completes. If the return value of this | ||
2301 | * function isn't an error, then this function | ||
2302 | * is guaranteed to be called when the | ||
2303 | * transaction completes. If this parameter is | ||
2304 | * NULL, then the generic callback registered | ||
2305 | * through cvmx_usb_register_callback is | ||
2306 | * called. If both are NULL, then there is no | ||
2307 | * way to know when a transaction completes. | ||
2308 | * @param user_data User supplied data returned when the | ||
2309 | * callback is called. This is only used if | ||
2310 | * callback in not NULL. | ||
2311 | * | ||
2312 | * @return A submitted transaction handle or negative on | ||
2313 | * failure. Negative values are failure codes from | ||
2314 | * cvmx_usb_status_t. | ||
2315 | */ | ||
2316 | int cvmx_usb_submit_bulk(cvmx_usb_state_t *state, int pipe_handle, | ||
2317 | uint64_t buffer, int buffer_length, | ||
2318 | cvmx_usb_callback_func_t callback, | ||
2319 | void *user_data) | ||
2320 | { | ||
2321 | int submit_handle; | ||
2322 | cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state; | ||
2323 | |||
2324 | CVMX_USB_LOG_CALLED(); | ||
2325 | CVMX_USB_LOG_PARAM("%p", state); | ||
2326 | CVMX_USB_LOG_PARAM("%d", pipe_handle); | ||
2327 | CVMX_USB_LOG_PARAM("0x%llx", (unsigned long long)buffer); | ||
2328 | CVMX_USB_LOG_PARAM("%d", buffer_length); | ||
2329 | |||
2330 | /* Pipe handle checking is done later in a common place */ | ||
2331 | if (cvmx_unlikely(!buffer)) | ||
2332 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2333 | if (cvmx_unlikely(buffer_length < 0)) | ||
2334 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2335 | |||
2336 | submit_handle = __cvmx_usb_submit_transaction(usb, pipe_handle, | ||
2337 | CVMX_USB_TRANSFER_BULK, | ||
2338 | 0, /* flags */ | ||
2339 | buffer, | ||
2340 | buffer_length, | ||
2341 | 0, /* control_header */ | ||
2342 | 0, /* iso_start_frame */ | ||
2343 | 0, /* iso_number_packets */ | ||
2344 | NULL, /* iso_packets */ | ||
2345 | callback, | ||
2346 | user_data); | ||
2347 | CVMX_USB_RETURN(submit_handle); | ||
2348 | } | ||
2349 | |||
2350 | |||
2351 | /** | ||
2352 | * Call to submit a USB Interrupt transfer to a pipe. | ||
2353 | * | ||
2354 | * @param state USB device state populated by | ||
2355 | * cvmx_usb_initialize(). | ||
2356 | * @param pipe_handle | ||
2357 | * Handle to the pipe for the transfer. | ||
2358 | * @param buffer Physical address of the data buffer in | ||
2359 | * memory. Note that this is NOT A POINTER, but | ||
2360 | * the full 64bit physical address of the | ||
2361 | * buffer. This may be zero if buffer_length is | ||
2362 | * zero. | ||
2363 | * @param buffer_length | ||
2364 | * Length of buffer in bytes. | ||
2365 | * @param callback Function to call when this transaction | ||
2366 | * completes. If the return value of this | ||
2367 | * function isn't an error, then this function | ||
2368 | * is guaranteed to be called when the | ||
2369 | * transaction completes. If this parameter is | ||
2370 | * NULL, then the generic callback registered | ||
2371 | * through cvmx_usb_register_callback is | ||
2372 | * called. If both are NULL, then there is no | ||
2373 | * way to know when a transaction completes. | ||
2374 | * @param user_data User supplied data returned when the | ||
2375 | * callback is called. This is only used if | ||
2376 | * callback in not NULL. | ||
2377 | * | ||
2378 | * @return A submitted transaction handle or negative on | ||
2379 | * failure. Negative values are failure codes from | ||
2380 | * cvmx_usb_status_t. | ||
2381 | */ | ||
2382 | int cvmx_usb_submit_interrupt(cvmx_usb_state_t *state, int pipe_handle, | ||
2383 | uint64_t buffer, int buffer_length, | ||
2384 | cvmx_usb_callback_func_t callback, | ||
2385 | void *user_data) | ||
2386 | { | ||
2387 | int submit_handle; | ||
2388 | cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state; | ||
2389 | |||
2390 | CVMX_USB_LOG_CALLED(); | ||
2391 | CVMX_USB_LOG_PARAM("%p", state); | ||
2392 | CVMX_USB_LOG_PARAM("%d", pipe_handle); | ||
2393 | CVMX_USB_LOG_PARAM("0x%llx", (unsigned long long)buffer); | ||
2394 | CVMX_USB_LOG_PARAM("%d", buffer_length); | ||
2395 | |||
2396 | /* Pipe handle checking is done later in a common place */ | ||
2397 | if (cvmx_unlikely(!buffer)) | ||
2398 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2399 | if (cvmx_unlikely(buffer_length < 0)) | ||
2400 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2401 | |||
2402 | submit_handle = __cvmx_usb_submit_transaction(usb, pipe_handle, | ||
2403 | CVMX_USB_TRANSFER_INTERRUPT, | ||
2404 | 0, /* flags */ | ||
2405 | buffer, | ||
2406 | buffer_length, | ||
2407 | 0, /* control_header */ | ||
2408 | 0, /* iso_start_frame */ | ||
2409 | 0, /* iso_number_packets */ | ||
2410 | NULL, /* iso_packets */ | ||
2411 | callback, | ||
2412 | user_data); | ||
2413 | CVMX_USB_RETURN(submit_handle); | ||
2414 | } | ||
2415 | |||
2416 | |||
2417 | /** | ||
2418 | * Call to submit a USB Control transfer to a pipe. | ||
2419 | * | ||
2420 | * @param state USB device state populated by | ||
2421 | * cvmx_usb_initialize(). | ||
2422 | * @param pipe_handle | ||
2423 | * Handle to the pipe for the transfer. | ||
2424 | * @param control_header | ||
2425 | * USB 8 byte control header physical address. | ||
2426 | * Note that this is NOT A POINTER, but the | ||
2427 | * full 64bit physical address of the buffer. | ||
2428 | * @param buffer Physical address of the data buffer in | ||
2429 | * memory. Note that this is NOT A POINTER, but | ||
2430 | * the full 64bit physical address of the | ||
2431 | * buffer. This may be zero if buffer_length is | ||
2432 | * zero. | ||
2433 | * @param buffer_length | ||
2434 | * Length of buffer in bytes. | ||
2435 | * @param callback Function to call when this transaction | ||
2436 | * completes. If the return value of this | ||
2437 | * function isn't an error, then this function | ||
2438 | * is guaranteed to be called when the | ||
2439 | * transaction completes. If this parameter is | ||
2440 | * NULL, then the generic callback registered | ||
2441 | * through cvmx_usb_register_callback is | ||
2442 | * called. If both are NULL, then there is no | ||
2443 | * way to know when a transaction completes. | ||
2444 | * @param user_data User supplied data returned when the | ||
2445 | * callback is called. This is only used if | ||
2446 | * callback in not NULL. | ||
2447 | * | ||
2448 | * @return A submitted transaction handle or negative on | ||
2449 | * failure. Negative values are failure codes from | ||
2450 | * cvmx_usb_status_t. | ||
2451 | */ | ||
2452 | int cvmx_usb_submit_control(cvmx_usb_state_t *state, int pipe_handle, | ||
2453 | uint64_t control_header, | ||
2454 | uint64_t buffer, int buffer_length, | ||
2455 | cvmx_usb_callback_func_t callback, | ||
2456 | void *user_data) | ||
2457 | { | ||
2458 | int submit_handle; | ||
2459 | cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state; | ||
2460 | cvmx_usb_control_header_t *header = cvmx_phys_to_ptr(control_header); | ||
2461 | |||
2462 | CVMX_USB_LOG_CALLED(); | ||
2463 | CVMX_USB_LOG_PARAM("%p", state); | ||
2464 | CVMX_USB_LOG_PARAM("%d", pipe_handle); | ||
2465 | CVMX_USB_LOG_PARAM("0x%llx", (unsigned long long)control_header); | ||
2466 | CVMX_USB_LOG_PARAM("0x%llx", (unsigned long long)buffer); | ||
2467 | CVMX_USB_LOG_PARAM("%d", buffer_length); | ||
2468 | |||
2469 | /* Pipe handle checking is done later in a common place */ | ||
2470 | if (cvmx_unlikely(!control_header)) | ||
2471 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2472 | /* Some drivers send a buffer with a zero length. God only knows why */ | ||
2473 | if (cvmx_unlikely(buffer && (buffer_length < 0))) | ||
2474 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2475 | if (cvmx_unlikely(!buffer && (buffer_length != 0))) | ||
2476 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2477 | if ((header->s.request_type & 0x80) == 0) | ||
2478 | buffer_length = cvmx_le16_to_cpu(header->s.length); | ||
2479 | |||
2480 | submit_handle = __cvmx_usb_submit_transaction(usb, pipe_handle, | ||
2481 | CVMX_USB_TRANSFER_CONTROL, | ||
2482 | 0, /* flags */ | ||
2483 | buffer, | ||
2484 | buffer_length, | ||
2485 | control_header, | ||
2486 | 0, /* iso_start_frame */ | ||
2487 | 0, /* iso_number_packets */ | ||
2488 | NULL, /* iso_packets */ | ||
2489 | callback, | ||
2490 | user_data); | ||
2491 | CVMX_USB_RETURN(submit_handle); | ||
2492 | } | ||
2493 | |||
2494 | |||
2495 | /** | ||
2496 | * Call to submit a USB Isochronous transfer to a pipe. | ||
2497 | * | ||
2498 | * @param state USB device state populated by | ||
2499 | * cvmx_usb_initialize(). | ||
2500 | * @param pipe_handle | ||
2501 | * Handle to the pipe for the transfer. | ||
2502 | * @param start_frame | ||
2503 | * Number of frames into the future to schedule | ||
2504 | * this transaction. | ||
2505 | * @param flags Flags to control the transfer. See | ||
2506 | * cvmx_usb_isochronous_flags_t for the flag | ||
2507 | * definitions. | ||
2508 | * @param number_packets | ||
2509 | * Number of sequential packets to transfer. | ||
2510 | * "packets" is a pointer to an array of this | ||
2511 | * many packet structures. | ||
2512 | * @param packets Description of each transfer packet as | ||
2513 | * defined by cvmx_usb_iso_packet_t. The array | ||
2514 | * pointed to here must stay valid until the | ||
2515 | * complete callback is called. | ||
2516 | * @param buffer Physical address of the data buffer in | ||
2517 | * memory. Note that this is NOT A POINTER, but | ||
2518 | * the full 64bit physical address of the | ||
2519 | * buffer. This may be zero if buffer_length is | ||
2520 | * zero. | ||
2521 | * @param buffer_length | ||
2522 | * Length of buffer in bytes. | ||
2523 | * @param callback Function to call when this transaction | ||
2524 | * completes. If the return value of this | ||
2525 | * function isn't an error, then this function | ||
2526 | * is guaranteed to be called when the | ||
2527 | * transaction completes. If this parameter is | ||
2528 | * NULL, then the generic callback registered | ||
2529 | * through cvmx_usb_register_callback is | ||
2530 | * called. If both are NULL, then there is no | ||
2531 | * way to know when a transaction completes. | ||
2532 | * @param user_data User supplied data returned when the | ||
2533 | * callback is called. This is only used if | ||
2534 | * callback in not NULL. | ||
2535 | * | ||
2536 | * @return A submitted transaction handle or negative on | ||
2537 | * failure. Negative values are failure codes from | ||
2538 | * cvmx_usb_status_t. | ||
2539 | */ | ||
2540 | int cvmx_usb_submit_isochronous(cvmx_usb_state_t *state, int pipe_handle, | ||
2541 | int start_frame, int flags, | ||
2542 | int number_packets, | ||
2543 | cvmx_usb_iso_packet_t packets[], | ||
2544 | uint64_t buffer, int buffer_length, | ||
2545 | cvmx_usb_callback_func_t callback, | ||
2546 | void *user_data) | ||
2547 | { | ||
2548 | int submit_handle; | ||
2549 | cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state; | ||
2550 | |||
2551 | CVMX_USB_LOG_CALLED(); | ||
2552 | CVMX_USB_LOG_PARAM("%p", state); | ||
2553 | CVMX_USB_LOG_PARAM("%d", pipe_handle); | ||
2554 | CVMX_USB_LOG_PARAM("%d", start_frame); | ||
2555 | CVMX_USB_LOG_PARAM("0x%x", flags); | ||
2556 | CVMX_USB_LOG_PARAM("%d", number_packets); | ||
2557 | CVMX_USB_LOG_PARAM("%p", packets); | ||
2558 | CVMX_USB_LOG_PARAM("0x%llx", (unsigned long long)buffer); | ||
2559 | CVMX_USB_LOG_PARAM("%d", buffer_length); | ||
2560 | |||
2561 | /* Pipe handle checking is done later in a common place */ | ||
2562 | if (cvmx_unlikely(start_frame < 0)) | ||
2563 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2564 | if (cvmx_unlikely(flags & ~(CVMX_USB_ISOCHRONOUS_FLAGS_ALLOW_SHORT | CVMX_USB_ISOCHRONOUS_FLAGS_ASAP))) | ||
2565 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2566 | if (cvmx_unlikely(number_packets < 1)) | ||
2567 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2568 | if (cvmx_unlikely(!packets)) | ||
2569 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2570 | if (cvmx_unlikely(!buffer)) | ||
2571 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2572 | if (cvmx_unlikely(buffer_length < 0)) | ||
2573 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2574 | |||
2575 | submit_handle = __cvmx_usb_submit_transaction(usb, pipe_handle, | ||
2576 | CVMX_USB_TRANSFER_ISOCHRONOUS, | ||
2577 | flags, | ||
2578 | buffer, | ||
2579 | buffer_length, | ||
2580 | 0, /* control_header */ | ||
2581 | start_frame, | ||
2582 | number_packets, | ||
2583 | packets, | ||
2584 | callback, | ||
2585 | user_data); | ||
2586 | CVMX_USB_RETURN(submit_handle); | ||
2587 | } | ||
2588 | |||
2589 | |||
2590 | /** | ||
2591 | * Cancel one outstanding request in a pipe. Canceling a request | ||
2592 | * can fail if the transaction has already completed before cancel | ||
2593 | * is called. Even after a successful cancel call, it may take | ||
2594 | * a frame or two for the cvmx_usb_poll() function to call the | ||
2595 | * associated callback. | ||
2596 | * | ||
2597 | * @param state USB device state populated by | ||
2598 | * cvmx_usb_initialize(). | ||
2599 | * @param pipe_handle | ||
2600 | * Pipe handle to cancel requests in. | ||
2601 | * @param submit_handle | ||
2602 | * Handle to transaction to cancel, returned by the submit function. | ||
2603 | * | ||
2604 | * @return CVMX_USB_SUCCESS or a negative error code defined in | ||
2605 | * cvmx_usb_status_t. | ||
2606 | */ | ||
2607 | cvmx_usb_status_t cvmx_usb_cancel(cvmx_usb_state_t *state, int pipe_handle, | ||
2608 | int submit_handle) | ||
2609 | { | ||
2610 | cvmx_usb_transaction_t *transaction; | ||
2611 | cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state; | ||
2612 | cvmx_usb_pipe_t *pipe = usb->pipe + pipe_handle; | ||
2613 | |||
2614 | CVMX_USB_LOG_CALLED(); | ||
2615 | CVMX_USB_LOG_PARAM("%p", state); | ||
2616 | CVMX_USB_LOG_PARAM("%d", pipe_handle); | ||
2617 | CVMX_USB_LOG_PARAM("%d", submit_handle); | ||
2618 | |||
2619 | if (cvmx_unlikely((pipe_handle < 0) || (pipe_handle >= MAX_PIPES))) | ||
2620 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2621 | if (cvmx_unlikely((submit_handle < 0) || (submit_handle >= MAX_TRANSACTIONS))) | ||
2622 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2623 | |||
2624 | /* Fail if the pipe isn't open */ | ||
2625 | if (cvmx_unlikely((pipe->flags & __CVMX_USB_PIPE_FLAGS_OPEN) == 0)) | ||
2626 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2627 | |||
2628 | transaction = usb->transaction + submit_handle; | ||
2629 | |||
2630 | /* Fail if this transaction already completed */ | ||
2631 | if (cvmx_unlikely((transaction->flags & __CVMX_USB_TRANSACTION_FLAGS_IN_USE) == 0)) | ||
2632 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2633 | |||
2634 | /* If the transaction is the HEAD of the queue and scheduled. We need to | ||
2635 | treat it special */ | ||
2636 | if ((pipe->head == transaction) && | ||
2637 | (pipe->flags & __CVMX_USB_PIPE_FLAGS_SCHEDULED)) | ||
2638 | { | ||
2639 | cvmx_usbcx_hccharx_t usbc_hcchar; | ||
2640 | |||
2641 | usb->pipe_for_channel[pipe->channel] = NULL; | ||
2642 | pipe->flags &= ~__CVMX_USB_PIPE_FLAGS_SCHEDULED; | ||
2643 | |||
2644 | CVMX_SYNCW; | ||
2645 | |||
2646 | usbc_hcchar.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCCHARX(pipe->channel, usb->index)); | ||
2647 | /* If the channel isn't enabled then the transaction already completed */ | ||
2648 | if (usbc_hcchar.s.chena) | ||
2649 | { | ||
2650 | usbc_hcchar.s.chdis = 1; | ||
2651 | __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCCHARX(pipe->channel, usb->index), usbc_hcchar.u32); | ||
2652 | } | ||
2653 | } | ||
2654 | __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_CANCEL); | ||
2655 | CVMX_USB_RETURN(CVMX_USB_SUCCESS); | ||
2656 | } | ||
2657 | |||
2658 | |||
2659 | /** | ||
2660 | * Cancel all outstanding requests in a pipe. Logically all this | ||
2661 | * does is call cvmx_usb_cancel() in a loop. | ||
2662 | * | ||
2663 | * @param state USB device state populated by | ||
2664 | * cvmx_usb_initialize(). | ||
2665 | * @param pipe_handle | ||
2666 | * Pipe handle to cancel requests in. | ||
2667 | * | ||
2668 | * @return CVMX_USB_SUCCESS or a negative error code defined in | ||
2669 | * cvmx_usb_status_t. | ||
2670 | */ | ||
2671 | cvmx_usb_status_t cvmx_usb_cancel_all(cvmx_usb_state_t *state, int pipe_handle) | ||
2672 | { | ||
2673 | cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state; | ||
2674 | cvmx_usb_pipe_t *pipe = usb->pipe + pipe_handle; | ||
2675 | |||
2676 | CVMX_USB_LOG_CALLED(); | ||
2677 | CVMX_USB_LOG_PARAM("%p", state); | ||
2678 | CVMX_USB_LOG_PARAM("%d", pipe_handle); | ||
2679 | if (cvmx_unlikely((pipe_handle < 0) || (pipe_handle >= MAX_PIPES))) | ||
2680 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2681 | |||
2682 | /* Fail if the pipe isn't open */ | ||
2683 | if (cvmx_unlikely((pipe->flags & __CVMX_USB_PIPE_FLAGS_OPEN) == 0)) | ||
2684 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2685 | |||
2686 | /* Simply loop through and attempt to cancel each transaction */ | ||
2687 | while (pipe->head) | ||
2688 | { | ||
2689 | cvmx_usb_status_t result = cvmx_usb_cancel(state, pipe_handle, | ||
2690 | __cvmx_usb_get_submit_handle(usb, pipe->head)); | ||
2691 | if (cvmx_unlikely(result != CVMX_USB_SUCCESS)) | ||
2692 | CVMX_USB_RETURN(result); | ||
2693 | } | ||
2694 | CVMX_USB_RETURN(CVMX_USB_SUCCESS); | ||
2695 | } | ||
2696 | |||
2697 | |||
2698 | /** | ||
2699 | * Close a pipe created with cvmx_usb_open_pipe(). | ||
2700 | * | ||
2701 | * @param state USB device state populated by | ||
2702 | * cvmx_usb_initialize(). | ||
2703 | * @param pipe_handle | ||
2704 | * Pipe handle to close. | ||
2705 | * | ||
2706 | * @return CVMX_USB_SUCCESS or a negative error code defined in | ||
2707 | * cvmx_usb_status_t. CVMX_USB_BUSY is returned if the | ||
2708 | * pipe has outstanding transfers. | ||
2709 | */ | ||
2710 | cvmx_usb_status_t cvmx_usb_close_pipe(cvmx_usb_state_t *state, int pipe_handle) | ||
2711 | { | ||
2712 | cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state; | ||
2713 | cvmx_usb_pipe_t *pipe = usb->pipe + pipe_handle; | ||
2714 | |||
2715 | CVMX_USB_LOG_CALLED(); | ||
2716 | CVMX_USB_LOG_PARAM("%p", state); | ||
2717 | CVMX_USB_LOG_PARAM("%d", pipe_handle); | ||
2718 | if (cvmx_unlikely((pipe_handle < 0) || (pipe_handle >= MAX_PIPES))) | ||
2719 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2720 | |||
2721 | /* Fail if the pipe isn't open */ | ||
2722 | if (cvmx_unlikely((pipe->flags & __CVMX_USB_PIPE_FLAGS_OPEN) == 0)) | ||
2723 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2724 | |||
2725 | /* Fail if the pipe has pending transactions */ | ||
2726 | if (cvmx_unlikely(pipe->head)) | ||
2727 | CVMX_USB_RETURN(CVMX_USB_BUSY); | ||
2728 | |||
2729 | pipe->flags = 0; | ||
2730 | __cvmx_usb_remove_pipe(&usb->idle_pipes, pipe); | ||
2731 | __cvmx_usb_append_pipe(&usb->free_pipes, pipe); | ||
2732 | |||
2733 | CVMX_USB_RETURN(CVMX_USB_SUCCESS); | ||
2734 | } | ||
2735 | |||
2736 | |||
2737 | /** | ||
2738 | * Register a function to be called when various USB events occur. | ||
2739 | * | ||
2740 | * @param state USB device state populated by | ||
2741 | * cvmx_usb_initialize(). | ||
2742 | * @param reason Which event to register for. | ||
2743 | * @param callback Function to call when the event occurs. | ||
2744 | * @param user_data User data parameter to the function. | ||
2745 | * | ||
2746 | * @return CVMX_USB_SUCCESS or a negative error code defined in | ||
2747 | * cvmx_usb_status_t. | ||
2748 | */ | ||
2749 | cvmx_usb_status_t cvmx_usb_register_callback(cvmx_usb_state_t *state, | ||
2750 | cvmx_usb_callback_t reason, | ||
2751 | cvmx_usb_callback_func_t callback, | ||
2752 | void *user_data) | ||
2753 | { | ||
2754 | cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state; | ||
2755 | |||
2756 | CVMX_USB_LOG_CALLED(); | ||
2757 | CVMX_USB_LOG_PARAM("%p", state); | ||
2758 | CVMX_USB_LOG_PARAM("%d", reason); | ||
2759 | CVMX_USB_LOG_PARAM("%p", callback); | ||
2760 | CVMX_USB_LOG_PARAM("%p", user_data); | ||
2761 | if (cvmx_unlikely(reason >= __CVMX_USB_CALLBACK_END)) | ||
2762 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2763 | if (cvmx_unlikely(!callback)) | ||
2764 | CVMX_USB_RETURN(CVMX_USB_INVALID_PARAM); | ||
2765 | |||
2766 | usb->callback[reason] = callback; | ||
2767 | usb->callback_data[reason] = user_data; | ||
2768 | |||
2769 | CVMX_USB_RETURN(CVMX_USB_SUCCESS); | ||
2770 | } | ||
2771 | |||
2772 | |||
2773 | /** | ||
2774 | * Get the current USB protocol level frame number. The frame | ||
2775 | * number is always in the range of 0-0x7ff. | ||
2776 | * | ||
2777 | * @param state USB device state populated by | ||
2778 | * cvmx_usb_initialize(). | ||
2779 | * | ||
2780 | * @return USB frame number | ||
2781 | */ | ||
2782 | int cvmx_usb_get_frame_number(cvmx_usb_state_t *state) | ||
2783 | { | ||
2784 | int frame_number; | ||
2785 | cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state; | ||
2786 | cvmx_usbcx_hfnum_t usbc_hfnum; | ||
2787 | |||
2788 | CVMX_USB_LOG_CALLED(); | ||
2789 | CVMX_USB_LOG_PARAM("%p", state); | ||
2790 | |||
2791 | usbc_hfnum.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index)); | ||
2792 | frame_number = usbc_hfnum.s.frnum; | ||
2793 | |||
2794 | CVMX_USB_RETURN(frame_number); | ||
2795 | } | ||
2796 | |||
2797 | |||
2798 | /** | ||
2799 | * @INTERNAL | ||
2800 | * Poll a channel for status | ||
2801 | * | ||
2802 | * @param usb USB device | ||
2803 | * @param channel Channel to poll | ||
2804 | * | ||
2805 | * @return Zero on success | ||
2806 | */ | ||
2807 | static int __cvmx_usb_poll_channel(cvmx_usb_internal_state_t *usb, int channel) | ||
2808 | { | ||
2809 | cvmx_usbcx_hcintx_t usbc_hcint; | ||
2810 | cvmx_usbcx_hctsizx_t usbc_hctsiz; | ||
2811 | cvmx_usbcx_hccharx_t usbc_hcchar; | ||
2812 | cvmx_usb_pipe_t *pipe; | ||
2813 | cvmx_usb_transaction_t *transaction; | ||
2814 | int bytes_this_transfer; | ||
2815 | int bytes_in_last_packet; | ||
2816 | int packets_processed; | ||
2817 | int buffer_space_left; | ||
2818 | CVMX_USB_LOG_CALLED(); | ||
2819 | CVMX_USB_LOG_PARAM("%p", usb); | ||
2820 | CVMX_USB_LOG_PARAM("%d", channel); | ||
2821 | |||
2822 | /* Read the interrupt status bits for the channel */ | ||
2823 | usbc_hcint.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCINTX(channel, usb->index)); | ||
2824 | |||
2825 | if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA) | ||
2826 | { | ||
2827 | usbc_hcchar.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index)); | ||
2828 | |||
2829 | if (usbc_hcchar.s.chena && usbc_hcchar.s.chdis) | ||
2830 | { | ||
2831 | /* There seems to be a bug in CN31XX which can cause interrupt | ||
2832 | IN transfers to get stuck until we do a write of HCCHARX | ||
2833 | without changing things */ | ||
2834 | __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index), usbc_hcchar.u32); | ||
2835 | CVMX_USB_RETURN(0); | ||
2836 | } | ||
2837 | |||
2838 | /* In non DMA mode the channels don't halt themselves. We need to | ||
2839 | manually disable channels that are left running */ | ||
2840 | if (!usbc_hcint.s.chhltd) | ||
2841 | { | ||
2842 | if (usbc_hcchar.s.chena) | ||
2843 | { | ||
2844 | cvmx_usbcx_hcintmskx_t hcintmsk; | ||
2845 | /* Disable all interrupts except CHHLTD */ | ||
2846 | hcintmsk.u32 = 0; | ||
2847 | hcintmsk.s.chhltdmsk = 1; | ||
2848 | __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), hcintmsk.u32); | ||
2849 | usbc_hcchar.s.chdis = 1; | ||
2850 | __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index), usbc_hcchar.u32); | ||
2851 | CVMX_USB_RETURN(0); | ||
2852 | } | ||
2853 | else if (usbc_hcint.s.xfercompl) | ||
2854 | { | ||
2855 | /* Successful IN/OUT with transfer complete. Channel halt isn't needed */ | ||
2856 | } | ||
2857 | else | ||
2858 | { | ||
2859 | cvmx_dprintf("USB%d: Channel %d interrupt without halt\n", usb->index, channel); | ||
2860 | CVMX_USB_RETURN(0); | ||
2861 | } | ||
2862 | } | ||
2863 | } | ||
2864 | else | ||
2865 | { | ||
2866 | /* There is are no interrupts that we need to process when the channel is | ||
2867 | still running */ | ||
2868 | if (!usbc_hcint.s.chhltd) | ||
2869 | CVMX_USB_RETURN(0); | ||
2870 | } | ||
2871 | |||
2872 | /* Disable the channel interrupts now that it is done */ | ||
2873 | __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), 0); | ||
2874 | usb->idle_hardware_channels |= (1<<channel); | ||
2875 | |||
2876 | /* Make sure this channel is tied to a valid pipe */ | ||
2877 | pipe = usb->pipe_for_channel[channel]; | ||
2878 | CVMX_PREFETCH(pipe, 0); | ||
2879 | CVMX_PREFETCH(pipe, 128); | ||
2880 | if (!pipe) | ||
2881 | CVMX_USB_RETURN(0); | ||
2882 | transaction = pipe->head; | ||
2883 | CVMX_PREFETCH0(transaction); | ||
2884 | |||
2885 | /* Disconnect this pipe from the HW channel. Later the schedule function will | ||
2886 | figure out which pipe needs to go */ | ||
2887 | usb->pipe_for_channel[channel] = NULL; | ||
2888 | pipe->flags &= ~__CVMX_USB_PIPE_FLAGS_SCHEDULED; | ||
2889 | |||
2890 | /* Read the channel config info so we can figure out how much data | ||
2891 | transfered */ | ||
2892 | usbc_hcchar.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index)); | ||
2893 | usbc_hctsiz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index)); | ||
2894 | |||
2895 | /* Calculating the number of bytes successfully transferred is dependent on | ||
2896 | the transfer direction */ | ||
2897 | packets_processed = transaction->pktcnt - usbc_hctsiz.s.pktcnt; | ||
2898 | if (usbc_hcchar.s.epdir) | ||
2899 | { | ||
2900 | /* IN transactions are easy. For every byte received the hardware | ||
2901 | decrements xfersize. All we need to do is subtract the current | ||
2902 | value of xfersize from its starting value and we know how many | ||
2903 | bytes were written to the buffer */ | ||
2904 | bytes_this_transfer = transaction->xfersize - usbc_hctsiz.s.xfersize; | ||
2905 | } | ||
2906 | else | ||
2907 | { | ||
2908 | /* OUT transaction don't decrement xfersize. Instead pktcnt is | ||
2909 | decremented on every successful packet send. The hardware does | ||
2910 | this when it receives an ACK, or NYET. If it doesn't | ||
2911 | receive one of these responses pktcnt doesn't change */ | ||
2912 | bytes_this_transfer = packets_processed * usbc_hcchar.s.mps; | ||
2913 | /* The last packet may not be a full transfer if we didn't have | ||
2914 | enough data */ | ||
2915 | if (bytes_this_transfer > transaction->xfersize) | ||
2916 | bytes_this_transfer = transaction->xfersize; | ||
2917 | } | ||
2918 | /* Figure out how many bytes were in the last packet of the transfer */ | ||
2919 | if (packets_processed) | ||
2920 | bytes_in_last_packet = bytes_this_transfer - (packets_processed-1) * usbc_hcchar.s.mps; | ||
2921 | else | ||
2922 | bytes_in_last_packet = bytes_this_transfer; | ||
2923 | |||
2924 | /* As a special case, setup transactions output the setup header, not | ||
2925 | the user's data. For this reason we don't count setup data as bytes | ||
2926 | transferred */ | ||
2927 | if ((transaction->stage == CVMX_USB_STAGE_SETUP) || | ||
2928 | (transaction->stage == CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE)) | ||
2929 | bytes_this_transfer = 0; | ||
2930 | |||
2931 | /* Optional debug output */ | ||
2932 | if (cvmx_unlikely((usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_DEBUG_TRANSFERS) || | ||
2933 | (pipe->flags & CVMX_USB_PIPE_FLAGS_DEBUG_TRANSFERS))) | ||
2934 | cvmx_dprintf("%s: Channel %d halted. Pipe %d transaction %d stage %d bytes=%d\n", | ||
2935 | __FUNCTION__, channel, | ||
2936 | __cvmx_usb_get_pipe_handle(usb, pipe), | ||
2937 | __cvmx_usb_get_submit_handle(usb, transaction), | ||
2938 | transaction->stage, bytes_this_transfer); | ||
2939 | |||
2940 | /* Add the bytes transferred to the running total. It is important that | ||
2941 | bytes_this_transfer doesn't count any data that needs to be | ||
2942 | retransmitted */ | ||
2943 | transaction->actual_bytes += bytes_this_transfer; | ||
2944 | if (transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS) | ||
2945 | buffer_space_left = transaction->iso_packets[0].length - transaction->actual_bytes; | ||
2946 | else | ||
2947 | buffer_space_left = transaction->buffer_length - transaction->actual_bytes; | ||
2948 | |||
2949 | /* We need to remember the PID toggle state for the next transaction. The | ||
2950 | hardware already updated it for the next transaction */ | ||
2951 | pipe->pid_toggle = !(usbc_hctsiz.s.pid == 0); | ||
2952 | |||
2953 | /* For high speed bulk out, assume the next transaction will need to do a | ||
2954 | ping before proceeding. If this isn't true the ACK processing below | ||
2955 | will clear this flag */ | ||
2956 | if ((pipe->device_speed == CVMX_USB_SPEED_HIGH) && | ||
2957 | (pipe->transfer_type == CVMX_USB_TRANSFER_BULK) && | ||
2958 | (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT)) | ||
2959 | pipe->flags |= __CVMX_USB_PIPE_FLAGS_NEED_PING; | ||
2960 | |||
2961 | if (usbc_hcint.s.stall) | ||
2962 | { | ||
2963 | /* STALL as a response means this transaction cannot be completed | ||
2964 | because the device can't process transactions. Tell the user. Any | ||
2965 | data that was transferred will be counted on the actual bytes | ||
2966 | transferred */ | ||
2967 | pipe->pid_toggle = 0; | ||
2968 | __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_STALL); | ||
2969 | } | ||
2970 | else if (usbc_hcint.s.xacterr) | ||
2971 | { | ||
2972 | /* We know at least one packet worked if we get a ACK or NAK. Reset the retry counter */ | ||
2973 | if (usbc_hcint.s.nak || usbc_hcint.s.ack) | ||
2974 | transaction->retries = 0; | ||
2975 | transaction->retries++; | ||
2976 | if (transaction->retries > MAX_RETRIES) | ||
2977 | { | ||
2978 | /* XactErr as a response means the device signaled something wrong with | ||
2979 | the transfer. For example, PID toggle errors cause these */ | ||
2980 | __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_XACTERR); | ||
2981 | } | ||
2982 | else | ||
2983 | { | ||
2984 | /* If this was a split then clear our split in progress marker */ | ||
2985 | if (usb->active_split == transaction) | ||
2986 | usb->active_split = NULL; | ||
2987 | /* Rewind to the beginning of the transaction by anding off the | ||
2988 | split complete bit */ | ||
2989 | transaction->stage &= ~1; | ||
2990 | pipe->split_sc_frame = -1; | ||
2991 | pipe->next_tx_frame += pipe->interval; | ||
2992 | if (pipe->next_tx_frame < usb->frame_number) | ||
2993 | pipe->next_tx_frame = usb->frame_number + pipe->interval - | ||
2994 | (usb->frame_number - pipe->next_tx_frame) % pipe->interval; | ||
2995 | } | ||
2996 | } | ||
2997 | else if (usbc_hcint.s.bblerr) | ||
2998 | { | ||
2999 | /* Babble Error (BblErr) */ | ||
3000 | __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_BABBLEERR); | ||
3001 | } | ||
3002 | else if (usbc_hcint.s.datatglerr) | ||
3003 | { | ||
3004 | /* We'll retry the exact same transaction again */ | ||
3005 | transaction->retries++; | ||
3006 | } | ||
3007 | else if (usbc_hcint.s.nyet) | ||
3008 | { | ||
3009 | /* NYET as a response is only allowed in three cases: as a response to | ||
3010 | a ping, as a response to a split transaction, and as a response to | ||
3011 | a bulk out. The ping case is handled by hardware, so we only have | ||
3012 | splits and bulk out */ | ||
3013 | if (!__cvmx_usb_pipe_needs_split(usb, pipe)) | ||
3014 | { | ||
3015 | transaction->retries = 0; | ||
3016 | /* If there is more data to go then we need to try again. Otherwise | ||
3017 | this transaction is complete */ | ||
3018 | if ((buffer_space_left == 0) || (bytes_in_last_packet < pipe->max_packet)) | ||
3019 | __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS); | ||
3020 | } | ||
3021 | else | ||
3022 | { | ||
3023 | /* Split transactions retry the split complete 4 times then rewind | ||
3024 | to the start split and do the entire transactions again */ | ||
3025 | transaction->retries++; | ||
3026 | if ((transaction->retries & 0x3) == 0) | ||
3027 | { | ||
3028 | /* Rewind to the beginning of the transaction by anding off the | ||
3029 | split complete bit */ | ||
3030 | transaction->stage &= ~1; | ||
3031 | pipe->split_sc_frame = -1; | ||
3032 | } | ||
3033 | } | ||
3034 | } | ||
3035 | else if (usbc_hcint.s.ack) | ||
3036 | { | ||
3037 | transaction->retries = 0; | ||
3038 | /* The ACK bit can only be checked after the other error bits. This is | ||
3039 | because a multi packet transfer may succeed in a number of packets | ||
3040 | and then get a different response on the last packet. In this case | ||
3041 | both ACK and the last response bit will be set. If none of the | ||
3042 | other response bits is set, then the last packet must have been an | ||
3043 | ACK */ | ||
3044 | |||
3045 | /* Since we got an ACK, we know we don't need to do a ping on this | ||
3046 | pipe */ | ||
3047 | pipe->flags &= ~__CVMX_USB_PIPE_FLAGS_NEED_PING; | ||
3048 | |||
3049 | switch (transaction->type) | ||
3050 | { | ||
3051 | case CVMX_USB_TRANSFER_CONTROL: | ||
3052 | switch (transaction->stage) | ||
3053 | { | ||
3054 | case CVMX_USB_STAGE_NON_CONTROL: | ||
3055 | case CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE: | ||
3056 | /* This should be impossible */ | ||
3057 | __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_ERROR); | ||
3058 | break; | ||
3059 | case CVMX_USB_STAGE_SETUP: | ||
3060 | pipe->pid_toggle = 1; | ||
3061 | if (__cvmx_usb_pipe_needs_split(usb, pipe)) | ||
3062 | transaction->stage = CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE; | ||
3063 | else | ||
3064 | { | ||
3065 | cvmx_usb_control_header_t *header = cvmx_phys_to_ptr(transaction->control_header); | ||
3066 | if (header->s.length) | ||
3067 | transaction->stage = CVMX_USB_STAGE_DATA; | ||
3068 | else | ||
3069 | transaction->stage = CVMX_USB_STAGE_STATUS; | ||
3070 | } | ||
3071 | break; | ||
3072 | case CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE: | ||
3073 | { | ||
3074 | cvmx_usb_control_header_t *header = cvmx_phys_to_ptr(transaction->control_header); | ||
3075 | if (header->s.length) | ||
3076 | transaction->stage = CVMX_USB_STAGE_DATA; | ||
3077 | else | ||
3078 | transaction->stage = CVMX_USB_STAGE_STATUS; | ||
3079 | } | ||
3080 | break; | ||
3081 | case CVMX_USB_STAGE_DATA: | ||
3082 | if (__cvmx_usb_pipe_needs_split(usb, pipe)) | ||
3083 | { | ||
3084 | transaction->stage = CVMX_USB_STAGE_DATA_SPLIT_COMPLETE; | ||
3085 | /* For setup OUT data that are splits, the hardware | ||
3086 | doesn't appear to count transferred data. Here | ||
3087 | we manually update the data transferred */ | ||
3088 | if (!usbc_hcchar.s.epdir) | ||
3089 | { | ||
3090 | if (buffer_space_left < pipe->max_packet) | ||
3091 | transaction->actual_bytes += buffer_space_left; | ||
3092 | else | ||
3093 | transaction->actual_bytes += pipe->max_packet; | ||
3094 | } | ||
3095 | } | ||
3096 | else if ((buffer_space_left == 0) || (bytes_in_last_packet < pipe->max_packet)) | ||
3097 | { | ||
3098 | pipe->pid_toggle = 1; | ||
3099 | transaction->stage = CVMX_USB_STAGE_STATUS; | ||
3100 | } | ||
3101 | break; | ||
3102 | case CVMX_USB_STAGE_DATA_SPLIT_COMPLETE: | ||
3103 | if ((buffer_space_left == 0) || (bytes_in_last_packet < pipe->max_packet)) | ||
3104 | { | ||
3105 | pipe->pid_toggle = 1; | ||
3106 | transaction->stage = CVMX_USB_STAGE_STATUS; | ||
3107 | } | ||
3108 | else | ||
3109 | { | ||
3110 | transaction->stage = CVMX_USB_STAGE_DATA; | ||
3111 | } | ||
3112 | break; | ||
3113 | case CVMX_USB_STAGE_STATUS: | ||
3114 | if (__cvmx_usb_pipe_needs_split(usb, pipe)) | ||
3115 | transaction->stage = CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE; | ||
3116 | else | ||
3117 | __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS); | ||
3118 | break; | ||
3119 | case CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE: | ||
3120 | __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS); | ||
3121 | break; | ||
3122 | } | ||
3123 | break; | ||
3124 | case CVMX_USB_TRANSFER_BULK: | ||
3125 | case CVMX_USB_TRANSFER_INTERRUPT: | ||
3126 | /* The only time a bulk transfer isn't complete when | ||
3127 | it finishes with an ACK is during a split transaction. For | ||
3128 | splits we need to continue the transfer if more data is | ||
3129 | needed */ | ||
3130 | if (__cvmx_usb_pipe_needs_split(usb, pipe)) | ||
3131 | { | ||
3132 | if (transaction->stage == CVMX_USB_STAGE_NON_CONTROL) | ||
3133 | transaction->stage = CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE; | ||
3134 | else | ||
3135 | { | ||
3136 | if (buffer_space_left && (bytes_in_last_packet == pipe->max_packet)) | ||
3137 | transaction->stage = CVMX_USB_STAGE_NON_CONTROL; | ||
3138 | else | ||
3139 | { | ||
3140 | if (transaction->type == CVMX_USB_TRANSFER_INTERRUPT) | ||
3141 | pipe->next_tx_frame += pipe->interval; | ||
3142 | __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS); | ||
3143 | } | ||
3144 | } | ||
3145 | } | ||
3146 | else | ||
3147 | { | ||
3148 | if ((pipe->device_speed == CVMX_USB_SPEED_HIGH) && | ||
3149 | (pipe->transfer_type == CVMX_USB_TRANSFER_BULK) && | ||
3150 | (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) && | ||
3151 | (usbc_hcint.s.nak)) | ||
3152 | pipe->flags |= __CVMX_USB_PIPE_FLAGS_NEED_PING; | ||
3153 | if (!buffer_space_left || (bytes_in_last_packet < pipe->max_packet)) | ||
3154 | { | ||
3155 | if (transaction->type == CVMX_USB_TRANSFER_INTERRUPT) | ||
3156 | pipe->next_tx_frame += pipe->interval; | ||
3157 | __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS); | ||
3158 | } | ||
3159 | } | ||
3160 | break; | ||
3161 | case CVMX_USB_TRANSFER_ISOCHRONOUS: | ||
3162 | if (__cvmx_usb_pipe_needs_split(usb, pipe)) | ||
3163 | { | ||
3164 | /* ISOCHRONOUS OUT splits don't require a complete split stage. | ||
3165 | Instead they use a sequence of begin OUT splits to transfer | ||
3166 | the data 188 bytes at a time. Once the transfer is complete, | ||
3167 | the pipe sleeps until the next schedule interval */ | ||
3168 | if (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) | ||
3169 | { | ||
3170 | /* If no space left or this wasn't a max size packet then | ||
3171 | this transfer is complete. Otherwise start it again | ||
3172 | to send the next 188 bytes */ | ||
3173 | if (!buffer_space_left || (bytes_this_transfer < 188)) | ||
3174 | { | ||
3175 | pipe->next_tx_frame += pipe->interval; | ||
3176 | __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS); | ||
3177 | } | ||
3178 | } | ||
3179 | else | ||
3180 | { | ||
3181 | if (transaction->stage == CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE) | ||
3182 | { | ||
3183 | /* We are in the incoming data phase. Keep getting | ||
3184 | data until we run out of space or get a small | ||
3185 | packet */ | ||
3186 | if ((buffer_space_left == 0) || (bytes_in_last_packet < pipe->max_packet)) | ||
3187 | { | ||
3188 | pipe->next_tx_frame += pipe->interval; | ||
3189 | __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS); | ||
3190 | } | ||
3191 | } | ||
3192 | else | ||
3193 | transaction->stage = CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE; | ||
3194 | } | ||
3195 | } | ||
3196 | else | ||
3197 | { | ||
3198 | pipe->next_tx_frame += pipe->interval; | ||
3199 | __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS); | ||
3200 | } | ||
3201 | break; | ||
3202 | } | ||
3203 | } | ||
3204 | else if (usbc_hcint.s.nak) | ||
3205 | { | ||
3206 | /* If this was a split then clear our split in progress marker */ | ||
3207 | if (usb->active_split == transaction) | ||
3208 | usb->active_split = NULL; | ||
3209 | /* NAK as a response means the device couldn't accept the transaction, | ||
3210 | but it should be retried in the future. Rewind to the beginning of | ||
3211 | the transaction by anding off the split complete bit. Retry in the | ||
3212 | next interval */ | ||
3213 | transaction->retries = 0; | ||
3214 | transaction->stage &= ~1; | ||
3215 | pipe->next_tx_frame += pipe->interval; | ||
3216 | if (pipe->next_tx_frame < usb->frame_number) | ||
3217 | pipe->next_tx_frame = usb->frame_number + pipe->interval - | ||
3218 | (usb->frame_number - pipe->next_tx_frame) % pipe->interval; | ||
3219 | } | ||
3220 | else | ||
3221 | { | ||
3222 | cvmx_usb_port_status_t port; | ||
3223 | port = cvmx_usb_get_status((cvmx_usb_state_t *)usb); | ||
3224 | if (port.port_enabled) | ||
3225 | { | ||
3226 | /* We'll retry the exact same transaction again */ | ||
3227 | transaction->retries++; | ||
3228 | } | ||
3229 | else | ||
3230 | { | ||
3231 | /* We get channel halted interrupts with no result bits sets when the | ||
3232 | cable is unplugged */ | ||
3233 | __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_ERROR); | ||
3234 | } | ||
3235 | } | ||
3236 | CVMX_USB_RETURN(0); | ||
3237 | } | ||
3238 | |||
3239 | |||
3240 | /** | ||
3241 | * Poll the USB block for status and call all needed callback | ||
3242 | * handlers. This function is meant to be called in the interrupt | ||
3243 | * handler for the USB controller. It can also be called | ||
3244 | * periodically in a loop for non-interrupt based operation. | ||
3245 | * | ||
3246 | * @param state USB device state populated by | ||
3247 | * cvmx_usb_initialize(). | ||
3248 | * | ||
3249 | * @return CVMX_USB_SUCCESS or a negative error code defined in | ||
3250 | * cvmx_usb_status_t. | ||
3251 | */ | ||
3252 | cvmx_usb_status_t cvmx_usb_poll(cvmx_usb_state_t *state) | ||
3253 | { | ||
3254 | cvmx_usbcx_hfnum_t usbc_hfnum; | ||
3255 | cvmx_usbcx_gintsts_t usbc_gintsts; | ||
3256 | cvmx_usb_internal_state_t *usb = (cvmx_usb_internal_state_t*)state; | ||
3257 | |||
3258 | CVMX_PREFETCH(usb, 0); | ||
3259 | CVMX_PREFETCH(usb, 1*128); | ||
3260 | CVMX_PREFETCH(usb, 2*128); | ||
3261 | CVMX_PREFETCH(usb, 3*128); | ||
3262 | CVMX_PREFETCH(usb, 4*128); | ||
3263 | |||
3264 | CVMX_USB_LOG_CALLED(); | ||
3265 | CVMX_USB_LOG_PARAM("%p", state); | ||
3266 | |||
3267 | /* Update the frame counter */ | ||
3268 | usbc_hfnum.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index)); | ||
3269 | if ((usb->frame_number&0x3fff) > usbc_hfnum.s.frnum) | ||
3270 | usb->frame_number += 0x4000; | ||
3271 | usb->frame_number &= ~0x3fffull; | ||
3272 | usb->frame_number |= usbc_hfnum.s.frnum; | ||
3273 | |||
3274 | /* Read the pending interrupts */ | ||
3275 | usbc_gintsts.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GINTSTS(usb->index)); | ||
3276 | |||
3277 | /* Clear the interrupts now that we know about them */ | ||
3278 | __cvmx_usb_write_csr32(usb, CVMX_USBCX_GINTSTS(usb->index), usbc_gintsts.u32); | ||
3279 | |||
3280 | if (usbc_gintsts.s.rxflvl) | ||
3281 | { | ||
3282 | /* RxFIFO Non-Empty (RxFLvl) | ||
3283 | Indicates that there is at least one packet pending to be read | ||
3284 | from the RxFIFO. */ | ||
3285 | /* In DMA mode this is handled by hardware */ | ||
3286 | if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA) | ||
3287 | __cvmx_usb_poll_rx_fifo(usb); | ||
3288 | } | ||
3289 | if (usbc_gintsts.s.ptxfemp || usbc_gintsts.s.nptxfemp) | ||
3290 | { | ||
3291 | /* Fill the Tx FIFOs when not in DMA mode */ | ||
3292 | if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA) | ||
3293 | __cvmx_usb_poll_tx_fifo(usb); | ||
3294 | } | ||
3295 | if (usbc_gintsts.s.disconnint || usbc_gintsts.s.prtint) | ||
3296 | { | ||
3297 | cvmx_usbcx_hprt_t usbc_hprt; | ||
3298 | /* Disconnect Detected Interrupt (DisconnInt) | ||
3299 | Asserted when a device disconnect is detected. */ | ||
3300 | |||
3301 | /* Host Port Interrupt (PrtInt) | ||
3302 | The core sets this bit to indicate a change in port status of one | ||
3303 | of the O2P USB core ports in Host mode. The application must | ||
3304 | read the Host Port Control and Status (HPRT) register to | ||
3305 | determine the exact event that caused this interrupt. The | ||
3306 | application must clear the appropriate status bit in the Host Port | ||
3307 | Control and Status register to clear this bit. */ | ||
3308 | |||
3309 | /* Call the user's port callback */ | ||
3310 | __cvmx_usb_perform_callback(usb, NULL, NULL, | ||
3311 | CVMX_USB_CALLBACK_PORT_CHANGED, | ||
3312 | CVMX_USB_COMPLETE_SUCCESS); | ||
3313 | /* Clear the port change bits */ | ||
3314 | usbc_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index)); | ||
3315 | usbc_hprt.s.prtena = 0; | ||
3316 | __cvmx_usb_write_csr32(usb, CVMX_USBCX_HPRT(usb->index), usbc_hprt.u32); | ||
3317 | } | ||
3318 | if (usbc_gintsts.s.hchint) | ||
3319 | { | ||
3320 | /* Host Channels Interrupt (HChInt) | ||
3321 | The core sets this bit to indicate that an interrupt is pending on | ||
3322 | one of the channels of the core (in Host mode). The application | ||
3323 | must read the Host All Channels Interrupt (HAINT) register to | ||
3324 | determine the exact number of the channel on which the | ||
3325 | interrupt occurred, and then read the corresponding Host | ||
3326 | Channel-n Interrupt (HCINTn) register to determine the exact | ||
3327 | cause of the interrupt. The application must clear the | ||
3328 | appropriate status bit in the HCINTn register to clear this bit. */ | ||
3329 | cvmx_usbcx_haint_t usbc_haint; | ||
3330 | usbc_haint.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HAINT(usb->index)); | ||
3331 | while (usbc_haint.u32) | ||
3332 | { | ||
3333 | int channel; | ||
3334 | CVMX_CLZ(channel, usbc_haint.u32); | ||
3335 | channel = 31 - channel; | ||
3336 | __cvmx_usb_poll_channel(usb, channel); | ||
3337 | usbc_haint.u32 ^= 1<<channel; | ||
3338 | } | ||
3339 | } | ||
3340 | |||
3341 | __cvmx_usb_schedule(usb, usbc_gintsts.s.sof); | ||
3342 | |||
3343 | CVMX_USB_RETURN(CVMX_USB_SUCCESS); | ||
3344 | } | ||
diff --git a/drivers/staging/octeon-usb/cvmx-usb.h b/drivers/staging/octeon-usb/cvmx-usb.h new file mode 100644 index 000000000000..db9cc05e5d3c --- /dev/null +++ b/drivers/staging/octeon-usb/cvmx-usb.h | |||
@@ -0,0 +1,1085 @@ | |||
1 | /***********************license start*************** | ||
2 | * Copyright (c) 2003-2010 Cavium Networks (support@cavium.com). All rights | ||
3 | * reserved. | ||
4 | * | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions are | ||
8 | * met: | ||
9 | * | ||
10 | * * Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * | ||
13 | * * Redistributions in binary form must reproduce the above | ||
14 | * copyright notice, this list of conditions and the following | ||
15 | * disclaimer in the documentation and/or other materials provided | ||
16 | * with the distribution. | ||
17 | |||
18 | * * Neither the name of Cavium Networks nor the names of | ||
19 | * its contributors may be used to endorse or promote products | ||
20 | * derived from this software without specific prior written | ||
21 | * permission. | ||
22 | |||
23 | * This Software, including technical data, may be subject to U.S. export control | ||
24 | * laws, including the U.S. Export Administration Act and its associated | ||
25 | * regulations, and may be subject to export or import regulations in other | ||
26 | * countries. | ||
27 | |||
28 | * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" | ||
29 | * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR | ||
30 | * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO | ||
31 | * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR | ||
32 | * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM | ||
33 | * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, | ||
34 | * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF | ||
35 | * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR | ||
36 | * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR | ||
37 | * PERFORMANCE OF THE SOFTWARE LIES WITH YOU. | ||
38 | ***********************license end**************************************/ | ||
39 | |||
40 | |||
41 | /** | ||
42 | * @file | ||
43 | * | ||
44 | * "cvmx-usb.h" defines a set of low level USB functions to help | ||
45 | * developers create Octeon USB drivers for various operating | ||
46 | * systems. These functions provide a generic API to the Octeon | ||
47 | * USB blocks, hiding the internal hardware specific | ||
48 | * operations. | ||
49 | * | ||
50 | * At a high level the device driver needs to: | ||
51 | * | ||
52 | * -# Call cvmx_usb_get_num_ports() to get the number of | ||
53 | * supported ports. | ||
54 | * -# Call cvmx_usb_initialize() for each Octeon USB port. | ||
55 | * -# Enable the port using cvmx_usb_enable(). | ||
56 | * -# Either periodically, or in an interrupt handler, call | ||
57 | * cvmx_usb_poll() to service USB events. | ||
58 | * -# Manage pipes using cvmx_usb_open_pipe() and | ||
59 | * cvmx_usb_close_pipe(). | ||
60 | * -# Manage transfers using cvmx_usb_submit_*() and | ||
61 | * cvmx_usb_cancel*(). | ||
62 | * -# Shutdown USB on unload using cvmx_usb_shutdown(). | ||
63 | * | ||
64 | * To monitor USB status changes, the device driver must use | ||
65 | * cvmx_usb_register_callback() to register for events that it | ||
66 | * is interested in. Below are a few hints on successfully | ||
67 | * implementing a driver on top of this API. | ||
68 | * | ||
69 | * <h2>Initialization</h2> | ||
70 | * | ||
71 | * When a driver is first loaded, it is normally not necessary | ||
72 | * to bring up the USB port completely. Most operating systems | ||
73 | * expect to initialize and enable the port in two independent | ||
74 | * steps. Normally an operating system will probe hardware, | ||
75 | * initialize anything found, and then enable the hardware. | ||
76 | * | ||
77 | * In the probe phase you should: | ||
78 | * -# Use cvmx_usb_get_num_ports() to determine the number of | ||
79 | * USB port to be supported. | ||
80 | * -# Allocate space for a cvmx_usb_state_t structure for each | ||
81 | * port. | ||
82 | * -# Tell the operating system about each port | ||
83 | * | ||
84 | * In the initialization phase you should: | ||
85 | * -# Use cvmx_usb_initialize() on each port. | ||
86 | * -# Do not call cvmx_usb_enable(). This leaves the USB port in | ||
87 | * the disabled state until the operating system is ready. | ||
88 | * | ||
89 | * Finally, in the enable phase you should: | ||
90 | * -# Call cvmx_usb_enable() on the appropriate port. | ||
91 | * -# Note that some operating system use a RESET instead of an | ||
92 | * enable call. To implement RESET, you should call | ||
93 | * cvmx_usb_disable() followed by cvmx_usb_enable(). | ||
94 | * | ||
95 | * <h2>Locking</h2> | ||
96 | * | ||
97 | * All of the functions in the cvmx-usb API assume exclusive | ||
98 | * access to the USB hardware and internal data structures. This | ||
99 | * means that the driver must provide locking as necessary. | ||
100 | * | ||
101 | * In the single CPU state it is normally enough to disable | ||
102 | * interrupts before every call to cvmx_usb*() and enable them | ||
103 | * again after the call is complete. Keep in mind that it is | ||
104 | * very common for the callback handlers to make additional | ||
105 | * calls into cvmx-usb, so the disable/enable must be protected | ||
106 | * against recursion. As an example, the Linux kernel | ||
107 | * local_irq_save() and local_irq_restore() are perfect for this | ||
108 | * in the non SMP case. | ||
109 | * | ||
110 | * In the SMP case, locking is more complicated. For SMP you not | ||
111 | * only need to disable interrupts on the local core, but also | ||
112 | * take a lock to make sure that another core cannot call | ||
113 | * cvmx-usb. | ||
114 | * | ||
115 | * <h2>Port callback</h2> | ||
116 | * | ||
117 | * The port callback prototype needs to look as follows: | ||
118 | * | ||
119 | * void port_callback(cvmx_usb_state_t *usb, | ||
120 | * cvmx_usb_callback_t reason, | ||
121 | * cvmx_usb_complete_t status, | ||
122 | * int pipe_handle, | ||
123 | * int submit_handle, | ||
124 | * int bytes_transferred, | ||
125 | * void *user_data); | ||
126 | * - @b usb is the cvmx_usb_state_t for the port. | ||
127 | * - @b reason will always be | ||
128 | * CVMX_USB_CALLBACK_PORT_CHANGED. | ||
129 | * - @b status will always be CVMX_USB_COMPLETE_SUCCESS. | ||
130 | * - @b pipe_handle will always be -1. | ||
131 | * - @b submit_handle will always be -1. | ||
132 | * - @b bytes_transferred will always be 0. | ||
133 | * - @b user_data is the void pointer originally passed along | ||
134 | * with the callback. Use this for any state information you | ||
135 | * need. | ||
136 | * | ||
137 | * The port callback will be called whenever the user plugs / | ||
138 | * unplugs a device from the port. It will not be called when a | ||
139 | * device is plugged / unplugged from a hub connected to the | ||
140 | * root port. Normally all the callback needs to do is tell the | ||
141 | * operating system to poll the root hub for status. Under | ||
142 | * Linux, this is performed by calling usb_hcd_poll_rh_status(). | ||
143 | * In the Linux driver we use @b user_data. to pass around the | ||
144 | * Linux "hcd" structure. Once the port callback completes, | ||
145 | * Linux automatically calls octeon_usb_hub_status_data() which | ||
146 | * uses cvmx_usb_get_status() to determine the root port status. | ||
147 | * | ||
148 | * <h2>Complete callback</h2> | ||
149 | * | ||
150 | * The completion callback prototype needs to look as follows: | ||
151 | * | ||
152 | * void complete_callback(cvmx_usb_state_t *usb, | ||
153 | * cvmx_usb_callback_t reason, | ||
154 | * cvmx_usb_complete_t status, | ||
155 | * int pipe_handle, | ||
156 | * int submit_handle, | ||
157 | * int bytes_transferred, | ||
158 | * void *user_data); | ||
159 | * - @b usb is the cvmx_usb_state_t for the port. | ||
160 | * - @b reason will always be | ||
161 | * CVMX_USB_CALLBACK_TRANSFER_COMPLETE. | ||
162 | * - @b status will be one of the cvmx_usb_complete_t | ||
163 | * enumerations. | ||
164 | * - @b pipe_handle is the handle to the pipe the transaction | ||
165 | * was originally submitted on. | ||
166 | * - @b submit_handle is the handle returned by the original | ||
167 | * cvmx_usb_submit_* call. | ||
168 | * - @b bytes_transferred is the number of bytes successfully | ||
169 | * transferred in the transaction. This will be zero on most | ||
170 | * error conditions. | ||
171 | * - @b user_data is the void pointer originally passed along | ||
172 | * with the callback. Use this for any state information you | ||
173 | * need. For example, the Linux "urb" is stored in here in the | ||
174 | * Linux driver. | ||
175 | * | ||
176 | * In general your callback handler should use @b status and @b | ||
177 | * bytes_transferred to tell the operating system the how the | ||
178 | * transaction completed. Normally the pipe is not changed in | ||
179 | * this callback. | ||
180 | * | ||
181 | * <h2>Canceling transactions</h2> | ||
182 | * | ||
183 | * When a transaction is cancelled using cvmx_usb_cancel*(), the | ||
184 | * actual length of time until the complete callback is called | ||
185 | * can vary greatly. It may be called before cvmx_usb_cancel*() | ||
186 | * returns, or it may be called a number of usb frames in the | ||
187 | * future once the hardware frees the transaction. In either of | ||
188 | * these cases, the complete handler will receive | ||
189 | * CVMX_USB_COMPLETE_CANCEL. | ||
190 | * | ||
191 | * <h2>Handling pipes</h2> | ||
192 | * | ||
193 | * USB "pipes" is a software construct created by this API to | ||
194 | * enable the ordering of usb transactions to a device endpoint. | ||
195 | * Octeon's underlying hardware doesn't have any concept | ||
196 | * equivalent to "pipes". The hardware instead has eight | ||
197 | * channels that can be used simultaneously to have up to eight | ||
198 | * transaction in process at the same time. In order to maintain | ||
199 | * ordering in a pipe, the transactions for a pipe will only be | ||
200 | * active in one hardware channel at a time. From an API user's | ||
201 | * perspective, this doesn't matter but it can be helpful to | ||
202 | * keep this in mind when you are probing hardware while | ||
203 | * debugging. | ||
204 | * | ||
205 | * Also keep in mind that usb transactions contain state | ||
206 | * information about the previous transaction to the same | ||
207 | * endpoint. Each transaction has a PID toggle that changes 0/1 | ||
208 | * between each sub packet. This is maintained in the pipe data | ||
209 | * structures. For this reason, you generally cannot create and | ||
210 | * destroy a pipe for every transaction. A sequence of | ||
211 | * transaction to the same endpoint must use the same pipe. | ||
212 | * | ||
213 | * <h2>Root Hub</h2> | ||
214 | * | ||
215 | * Some operating systems view the usb root port as a normal usb | ||
216 | * hub. These systems attempt to control the root hub with | ||
217 | * messages similar to the usb 2.0 spec for hub control and | ||
218 | * status. For these systems it may be necessary to write | ||
219 | * function to decode standard usb control messages into | ||
220 | * equivalent cvmx-usb API calls. As an example, the following | ||
221 | * code is used under Linux for some of the basic hub control | ||
222 | * messages. | ||
223 | * | ||
224 | * @code | ||
225 | * static int octeon_usb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength) | ||
226 | * { | ||
227 | * cvmx_usb_state_t *usb = (cvmx_usb_state_t *)hcd->hcd_priv; | ||
228 | * cvmx_usb_port_status_t usb_port_status; | ||
229 | * int port_status; | ||
230 | * struct usb_hub_descriptor *desc; | ||
231 | * unsigned long flags; | ||
232 | * | ||
233 | * switch (typeReq) | ||
234 | * { | ||
235 | * case ClearHubFeature: | ||
236 | * DEBUG_ROOT_HUB("OcteonUSB: ClearHubFeature\n"); | ||
237 | * switch (wValue) | ||
238 | * { | ||
239 | * case C_HUB_LOCAL_POWER: | ||
240 | * case C_HUB_OVER_CURRENT: | ||
241 | * // Nothing required here | ||
242 | * break; | ||
243 | * default: | ||
244 | * return -EINVAL; | ||
245 | * } | ||
246 | * break; | ||
247 | * case ClearPortFeature: | ||
248 | * DEBUG_ROOT_HUB("OcteonUSB: ClearPortFeature"); | ||
249 | * if (wIndex != 1) | ||
250 | * { | ||
251 | * DEBUG_ROOT_HUB(" INVALID\n"); | ||
252 | * return -EINVAL; | ||
253 | * } | ||
254 | * | ||
255 | * switch (wValue) | ||
256 | * { | ||
257 | * case USB_PORT_FEAT_ENABLE: | ||
258 | * DEBUG_ROOT_HUB(" ENABLE"); | ||
259 | * local_irq_save(flags); | ||
260 | * cvmx_usb_disable(usb); | ||
261 | * local_irq_restore(flags); | ||
262 | * break; | ||
263 | * case USB_PORT_FEAT_SUSPEND: | ||
264 | * DEBUG_ROOT_HUB(" SUSPEND"); | ||
265 | * // Not supported on Octeon | ||
266 | * break; | ||
267 | * case USB_PORT_FEAT_POWER: | ||
268 | * DEBUG_ROOT_HUB(" POWER"); | ||
269 | * // Not supported on Octeon | ||
270 | * break; | ||
271 | * case USB_PORT_FEAT_INDICATOR: | ||
272 | * DEBUG_ROOT_HUB(" INDICATOR"); | ||
273 | * // Port inidicator not supported | ||
274 | * break; | ||
275 | * case USB_PORT_FEAT_C_CONNECTION: | ||
276 | * DEBUG_ROOT_HUB(" C_CONNECTION"); | ||
277 | * // Clears drivers internal connect status change flag | ||
278 | * cvmx_usb_set_status(usb, cvmx_usb_get_status(usb)); | ||
279 | * break; | ||
280 | * case USB_PORT_FEAT_C_RESET: | ||
281 | * DEBUG_ROOT_HUB(" C_RESET"); | ||
282 | * // Clears the driver's internal Port Reset Change flag | ||
283 | * cvmx_usb_set_status(usb, cvmx_usb_get_status(usb)); | ||
284 | * break; | ||
285 | * case USB_PORT_FEAT_C_ENABLE: | ||
286 | * DEBUG_ROOT_HUB(" C_ENABLE"); | ||
287 | * // Clears the driver's internal Port Enable/Disable Change flag | ||
288 | * cvmx_usb_set_status(usb, cvmx_usb_get_status(usb)); | ||
289 | * break; | ||
290 | * case USB_PORT_FEAT_C_SUSPEND: | ||
291 | * DEBUG_ROOT_HUB(" C_SUSPEND"); | ||
292 | * // Clears the driver's internal Port Suspend Change flag, | ||
293 | * which is set when resume signaling on the host port is | ||
294 | * complete | ||
295 | * break; | ||
296 | * case USB_PORT_FEAT_C_OVER_CURRENT: | ||
297 | * DEBUG_ROOT_HUB(" C_OVER_CURRENT"); | ||
298 | * // Clears the driver's overcurrent Change flag | ||
299 | * cvmx_usb_set_status(usb, cvmx_usb_get_status(usb)); | ||
300 | * break; | ||
301 | * default: | ||
302 | * DEBUG_ROOT_HUB(" UNKNOWN\n"); | ||
303 | * return -EINVAL; | ||
304 | * } | ||
305 | * DEBUG_ROOT_HUB("\n"); | ||
306 | * break; | ||
307 | * case GetHubDescriptor: | ||
308 | * DEBUG_ROOT_HUB("OcteonUSB: GetHubDescriptor\n"); | ||
309 | * desc = (struct usb_hub_descriptor *)buf; | ||
310 | * desc->bDescLength = 9; | ||
311 | * desc->bDescriptorType = 0x29; | ||
312 | * desc->bNbrPorts = 1; | ||
313 | * desc->wHubCharacteristics = 0x08; | ||
314 | * desc->bPwrOn2PwrGood = 1; | ||
315 | * desc->bHubContrCurrent = 0; | ||
316 | * desc->bitmap[0] = 0; | ||
317 | * desc->bitmap[1] = 0xff; | ||
318 | * break; | ||
319 | * case GetHubStatus: | ||
320 | * DEBUG_ROOT_HUB("OcteonUSB: GetHubStatus\n"); | ||
321 | * *(__le32 *)buf = 0; | ||
322 | * break; | ||
323 | * case GetPortStatus: | ||
324 | * DEBUG_ROOT_HUB("OcteonUSB: GetPortStatus"); | ||
325 | * if (wIndex != 1) | ||
326 | * { | ||
327 | * DEBUG_ROOT_HUB(" INVALID\n"); | ||
328 | * return -EINVAL; | ||
329 | * } | ||
330 | * | ||
331 | * usb_port_status = cvmx_usb_get_status(usb); | ||
332 | * port_status = 0; | ||
333 | * | ||
334 | * if (usb_port_status.connect_change) | ||
335 | * { | ||
336 | * port_status |= (1 << USB_PORT_FEAT_C_CONNECTION); | ||
337 | * DEBUG_ROOT_HUB(" C_CONNECTION"); | ||
338 | * } | ||
339 | * | ||
340 | * if (usb_port_status.port_enabled) | ||
341 | * { | ||
342 | * port_status |= (1 << USB_PORT_FEAT_C_ENABLE); | ||
343 | * DEBUG_ROOT_HUB(" C_ENABLE"); | ||
344 | * } | ||
345 | * | ||
346 | * if (usb_port_status.connected) | ||
347 | * { | ||
348 | * port_status |= (1 << USB_PORT_FEAT_CONNECTION); | ||
349 | * DEBUG_ROOT_HUB(" CONNECTION"); | ||
350 | * } | ||
351 | * | ||
352 | * if (usb_port_status.port_enabled) | ||
353 | * { | ||
354 | * port_status |= (1 << USB_PORT_FEAT_ENABLE); | ||
355 | * DEBUG_ROOT_HUB(" ENABLE"); | ||
356 | * } | ||
357 | * | ||
358 | * if (usb_port_status.port_over_current) | ||
359 | * { | ||
360 | * port_status |= (1 << USB_PORT_FEAT_OVER_CURRENT); | ||
361 | * DEBUG_ROOT_HUB(" OVER_CURRENT"); | ||
362 | * } | ||
363 | * | ||
364 | * if (usb_port_status.port_powered) | ||
365 | * { | ||
366 | * port_status |= (1 << USB_PORT_FEAT_POWER); | ||
367 | * DEBUG_ROOT_HUB(" POWER"); | ||
368 | * } | ||
369 | * | ||
370 | * if (usb_port_status.port_speed == CVMX_USB_SPEED_HIGH) | ||
371 | * { | ||
372 | * port_status |= (1 << USB_PORT_FEAT_HIGHSPEED); | ||
373 | * DEBUG_ROOT_HUB(" HIGHSPEED"); | ||
374 | * } | ||
375 | * else if (usb_port_status.port_speed == CVMX_USB_SPEED_LOW) | ||
376 | * { | ||
377 | * port_status |= (1 << USB_PORT_FEAT_LOWSPEED); | ||
378 | * DEBUG_ROOT_HUB(" LOWSPEED"); | ||
379 | * } | ||
380 | * | ||
381 | * *((__le32 *)buf) = cpu_to_le32(port_status); | ||
382 | * DEBUG_ROOT_HUB("\n"); | ||
383 | * break; | ||
384 | * case SetHubFeature: | ||
385 | * DEBUG_ROOT_HUB("OcteonUSB: SetHubFeature\n"); | ||
386 | * // No HUB features supported | ||
387 | * break; | ||
388 | * case SetPortFeature: | ||
389 | * DEBUG_ROOT_HUB("OcteonUSB: SetPortFeature"); | ||
390 | * if (wIndex != 1) | ||
391 | * { | ||
392 | * DEBUG_ROOT_HUB(" INVALID\n"); | ||
393 | * return -EINVAL; | ||
394 | * } | ||
395 | * | ||
396 | * switch (wValue) | ||
397 | * { | ||
398 | * case USB_PORT_FEAT_SUSPEND: | ||
399 | * DEBUG_ROOT_HUB(" SUSPEND\n"); | ||
400 | * return -EINVAL; | ||
401 | * case USB_PORT_FEAT_POWER: | ||
402 | * DEBUG_ROOT_HUB(" POWER\n"); | ||
403 | * return -EINVAL; | ||
404 | * case USB_PORT_FEAT_RESET: | ||
405 | * DEBUG_ROOT_HUB(" RESET\n"); | ||
406 | * local_irq_save(flags); | ||
407 | * cvmx_usb_disable(usb); | ||
408 | * if (cvmx_usb_enable(usb)) | ||
409 | * DEBUG_ERROR("Failed to enable the port\n"); | ||
410 | * local_irq_restore(flags); | ||
411 | * return 0; | ||
412 | * case USB_PORT_FEAT_INDICATOR: | ||
413 | * DEBUG_ROOT_HUB(" INDICATOR\n"); | ||
414 | * // Not supported | ||
415 | * break; | ||
416 | * default: | ||
417 | * DEBUG_ROOT_HUB(" UNKNOWN\n"); | ||
418 | * return -EINVAL; | ||
419 | * } | ||
420 | * break; | ||
421 | * default: | ||
422 | * DEBUG_ROOT_HUB("OcteonUSB: Unknown root hub request\n"); | ||
423 | * return -EINVAL; | ||
424 | * } | ||
425 | * return 0; | ||
426 | * } | ||
427 | * @endcode | ||
428 | * | ||
429 | * <h2>Interrupts</h2> | ||
430 | * | ||
431 | * If you plan on using usb interrupts, cvmx_usb_poll() must be | ||
432 | * called on every usb interrupt. It will read the usb state, | ||
433 | * call any needed callbacks, and schedule transactions as | ||
434 | * needed. Your device driver needs only to hookup an interrupt | ||
435 | * handler and call cvmx_usb_poll(). Octeon's usb port 0 causes | ||
436 | * CIU bit CIU_INT*_SUM0[USB] to be set (bit 56). For port 1, | ||
437 | * CIU bit CIU_INT_SUM1[USB1] is set (bit 17). How these bits | ||
438 | * are turned into interrupt numbers is operating system | ||
439 | * specific. For Linux, there are the convenient defines | ||
440 | * OCTEON_IRQ_USB0 and OCTEON_IRQ_USB1 for the IRQ numbers. | ||
441 | * | ||
442 | * If you aren't using interrupts, simple call cvmx_usb_poll() | ||
443 | * in your main processing loop. | ||
444 | * | ||
445 | * <hr>$Revision: 32636 $<hr> | ||
446 | */ | ||
447 | |||
448 | #ifndef __CVMX_USB_H__ | ||
449 | #define __CVMX_USB_H__ | ||
450 | |||
451 | #ifdef __cplusplus | ||
452 | extern "C" { | ||
453 | #endif | ||
454 | |||
455 | /** | ||
456 | * Enumerations representing the status of function calls. | ||
457 | */ | ||
458 | typedef enum | ||
459 | { | ||
460 | CVMX_USB_SUCCESS = 0, /**< There were no errors */ | ||
461 | CVMX_USB_INVALID_PARAM = -1, /**< A parameter to the function was invalid */ | ||
462 | CVMX_USB_NO_MEMORY = -2, /**< Insufficient resources were available for the request */ | ||
463 | CVMX_USB_BUSY = -3, /**< The resource is busy and cannot service the request */ | ||
464 | CVMX_USB_TIMEOUT = -4, /**< Waiting for an action timed out */ | ||
465 | CVMX_USB_INCORRECT_MODE = -5, /**< The function call doesn't work in the current USB | ||
466 | mode. This happens when host only functions are | ||
467 | called in device mode or vice versa */ | ||
468 | } cvmx_usb_status_t; | ||
469 | |||
470 | /** | ||
471 | * Enumerations representing the possible USB device speeds | ||
472 | */ | ||
473 | typedef enum | ||
474 | { | ||
475 | CVMX_USB_SPEED_HIGH = 0, /**< Device is operation at 480Mbps */ | ||
476 | CVMX_USB_SPEED_FULL = 1, /**< Device is operation at 12Mbps */ | ||
477 | CVMX_USB_SPEED_LOW = 2, /**< Device is operation at 1.5Mbps */ | ||
478 | } cvmx_usb_speed_t; | ||
479 | |||
480 | /** | ||
481 | * Enumeration representing the possible USB transfer types. | ||
482 | */ | ||
483 | typedef enum | ||
484 | { | ||
485 | CVMX_USB_TRANSFER_CONTROL = 0, /**< USB transfer type control for hub and status transfers */ | ||
486 | CVMX_USB_TRANSFER_ISOCHRONOUS = 1, /**< USB transfer type isochronous for low priority periodic transfers */ | ||
487 | CVMX_USB_TRANSFER_BULK = 2, /**< USB transfer type bulk for large low priority transfers */ | ||
488 | CVMX_USB_TRANSFER_INTERRUPT = 3, /**< USB transfer type interrupt for high priority periodic transfers */ | ||
489 | } cvmx_usb_transfer_t; | ||
490 | |||
491 | /** | ||
492 | * Enumeration of the transfer directions | ||
493 | */ | ||
494 | typedef enum | ||
495 | { | ||
496 | CVMX_USB_DIRECTION_OUT, /**< Data is transferring from Octeon to the device/host */ | ||
497 | CVMX_USB_DIRECTION_IN, /**< Data is transferring from the device/host to Octeon */ | ||
498 | } cvmx_usb_direction_t; | ||
499 | |||
500 | /** | ||
501 | * Enumeration of all possible status codes passed to callback | ||
502 | * functions. | ||
503 | */ | ||
504 | typedef enum | ||
505 | { | ||
506 | CVMX_USB_COMPLETE_SUCCESS, /**< The transaction / operation finished without any errors */ | ||
507 | CVMX_USB_COMPLETE_SHORT, /**< FIXME: This is currently not implemented */ | ||
508 | CVMX_USB_COMPLETE_CANCEL, /**< The transaction was canceled while in flight by a user call to cvmx_usb_cancel* */ | ||
509 | CVMX_USB_COMPLETE_ERROR, /**< The transaction aborted with an unexpected error status */ | ||
510 | CVMX_USB_COMPLETE_STALL, /**< The transaction received a USB STALL response from the device */ | ||
511 | CVMX_USB_COMPLETE_XACTERR, /**< The transaction failed with an error from the device even after a number of retries */ | ||
512 | CVMX_USB_COMPLETE_DATATGLERR, /**< The transaction failed with a data toggle error even after a number of retries */ | ||
513 | CVMX_USB_COMPLETE_BABBLEERR, /**< The transaction failed with a babble error */ | ||
514 | CVMX_USB_COMPLETE_FRAMEERR, /**< The transaction failed with a frame error even after a number of retries */ | ||
515 | } cvmx_usb_complete_t; | ||
516 | |||
517 | /** | ||
518 | * Structure returned containing the USB port status information. | ||
519 | */ | ||
520 | typedef struct | ||
521 | { | ||
522 | uint32_t reserved : 25; | ||
523 | uint32_t port_enabled : 1; /**< 1 = Usb port is enabled, 0 = disabled */ | ||
524 | uint32_t port_over_current : 1; /**< 1 = Over current detected, 0 = Over current not detected. Octeon doesn't support over current detection */ | ||
525 | uint32_t port_powered : 1; /**< 1 = Port power is being supplied to the device, 0 = power is off. Octeon doesn't support turning port power off */ | ||
526 | cvmx_usb_speed_t port_speed : 2; /**< Current port speed */ | ||
527 | uint32_t connected : 1; /**< 1 = A device is connected to the port, 0 = No device is connected */ | ||
528 | uint32_t connect_change : 1; /**< 1 = Device connected state changed since the last set status call */ | ||
529 | } cvmx_usb_port_status_t; | ||
530 | |||
531 | /** | ||
532 | * This is the structure of a Control packet header | ||
533 | */ | ||
534 | typedef union | ||
535 | { | ||
536 | uint64_t u64; | ||
537 | struct | ||
538 | { | ||
539 | uint64_t request_type : 8; /**< Bit 7 tells the direction: 1=IN, 0=OUT */ | ||
540 | uint64_t request : 8; /**< The standard usb request to make */ | ||
541 | uint64_t value : 16; /**< Value parameter for the request in little endian format */ | ||
542 | uint64_t index : 16; /**< Index for the request in little endian format */ | ||
543 | uint64_t length : 16; /**< Length of the data associated with this request in little endian format */ | ||
544 | } s; | ||
545 | } cvmx_usb_control_header_t; | ||
546 | |||
547 | /** | ||
548 | * Descriptor for Isochronous packets | ||
549 | */ | ||
550 | typedef struct | ||
551 | { | ||
552 | int offset; /**< This is the offset in bytes into the main buffer where this data is stored */ | ||
553 | int length; /**< This is the length in bytes of the data */ | ||
554 | cvmx_usb_complete_t status; /**< This is the status of this individual packet transfer */ | ||
555 | } cvmx_usb_iso_packet_t; | ||
556 | |||
557 | /** | ||
558 | * Possible callback reasons for the USB API. | ||
559 | */ | ||
560 | typedef enum | ||
561 | { | ||
562 | CVMX_USB_CALLBACK_TRANSFER_COMPLETE, | ||
563 | /**< A callback of this type is called when a submitted transfer | ||
564 | completes. The completion callback will be called even if the | ||
565 | transfer fails or is canceled. The status parameter will | ||
566 | contain details of why he callback was called. */ | ||
567 | CVMX_USB_CALLBACK_PORT_CHANGED, /**< The status of the port changed. For example, someone may have | ||
568 | plugged a device in. The status parameter contains | ||
569 | CVMX_USB_COMPLETE_SUCCESS. Use cvmx_usb_get_status() to get | ||
570 | the new port status. */ | ||
571 | __CVMX_USB_CALLBACK_END /**< Do not use. Used internally for array bounds */ | ||
572 | } cvmx_usb_callback_t; | ||
573 | |||
574 | /** | ||
575 | * USB state internal data. The contents of this structure | ||
576 | * may change in future SDKs. No data in it should be referenced | ||
577 | * by user's of this API. | ||
578 | */ | ||
579 | typedef struct | ||
580 | { | ||
581 | char data[65536]; | ||
582 | } cvmx_usb_state_t; | ||
583 | |||
584 | /** | ||
585 | * USB callback functions are always of the following type. | ||
586 | * The parameters are as follows: | ||
587 | * - state = USB device state populated by | ||
588 | * cvmx_usb_initialize(). | ||
589 | * - reason = The cvmx_usb_callback_t used to register | ||
590 | * the callback. | ||
591 | * - status = The cvmx_usb_complete_t representing the | ||
592 | * status code of a transaction. | ||
593 | * - pipe_handle = The Pipe that caused this callback, or | ||
594 | * -1 if this callback wasn't associated with a pipe. | ||
595 | * - submit_handle = Transfer submit handle causing this | ||
596 | * callback, or -1 if this callback wasn't associated | ||
597 | * with a transfer. | ||
598 | * - Actual number of bytes transfer. | ||
599 | * - user_data = The user pointer supplied to the | ||
600 | * function cvmx_usb_submit() or | ||
601 | * cvmx_usb_register_callback() */ | ||
602 | typedef void (*cvmx_usb_callback_func_t)(cvmx_usb_state_t *state, | ||
603 | cvmx_usb_callback_t reason, | ||
604 | cvmx_usb_complete_t status, | ||
605 | int pipe_handle, int submit_handle, | ||
606 | int bytes_transferred, void *user_data); | ||
607 | |||
608 | /** | ||
609 | * Flags to pass the initialization function. | ||
610 | */ | ||
611 | typedef enum | ||
612 | { | ||
613 | CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI = 1<<0, /**< The USB port uses a 12MHz crystal as clock source | ||
614 | at USB_XO and USB_XI. */ | ||
615 | CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND = 1<<1, /**< The USB port uses 12/24/48MHz 2.5V board clock | ||
616 | source at USB_XO. USB_XI should be tied to GND.*/ | ||
617 | CVMX_USB_INITIALIZE_FLAGS_CLOCK_AUTO = 0, /**< Automatically determine clock type based on function | ||
618 | in cvmx-helper-board.c. */ | ||
619 | CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK = 3<<3, /**< Mask for clock speed field */ | ||
620 | CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ = 1<<3, /**< Speed of reference clock or crystal */ | ||
621 | CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ = 2<<3, /**< Speed of reference clock */ | ||
622 | CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ = 3<<3, /**< Speed of reference clock */ | ||
623 | /* Bits 3-4 used to encode the clock frequency */ | ||
624 | CVMX_USB_INITIALIZE_FLAGS_NO_DMA = 1<<5, /**< Disable DMA and used polled IO for data transfer use for the USB */ | ||
625 | CVMX_USB_INITIALIZE_FLAGS_DEBUG_TRANSFERS = 1<<16, /**< Enable extra console output for debugging USB transfers */ | ||
626 | CVMX_USB_INITIALIZE_FLAGS_DEBUG_CALLBACKS = 1<<17, /**< Enable extra console output for debugging USB callbacks */ | ||
627 | CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO = 1<<18, /**< Enable extra console output for USB informational data */ | ||
628 | CVMX_USB_INITIALIZE_FLAGS_DEBUG_CALLS = 1<<19, /**< Enable extra console output for every function call */ | ||
629 | CVMX_USB_INITIALIZE_FLAGS_DEBUG_CSRS = 1<<20, /**< Enable extra console output for every CSR access */ | ||
630 | CVMX_USB_INITIALIZE_FLAGS_DEBUG_ALL = ((CVMX_USB_INITIALIZE_FLAGS_DEBUG_CSRS<<1)-1) - (CVMX_USB_INITIALIZE_FLAGS_DEBUG_TRANSFERS-1), | ||
631 | } cvmx_usb_initialize_flags_t; | ||
632 | |||
633 | /** | ||
634 | * Flags for passing when a pipe is created. Currently no flags | ||
635 | * need to be passed. | ||
636 | */ | ||
637 | typedef enum | ||
638 | { | ||
639 | CVMX_USB_PIPE_FLAGS_DEBUG_TRANSFERS = 1<<15,/**< Used to display CVMX_USB_INITIALIZE_FLAGS_DEBUG_TRANSFERS for a specific pipe only */ | ||
640 | __CVMX_USB_PIPE_FLAGS_OPEN = 1<<16, /**< Used internally to determine if a pipe is open. Do not use */ | ||
641 | __CVMX_USB_PIPE_FLAGS_SCHEDULED = 1<<17, /**< Used internally to determine if a pipe is actively using hardware. Do not use */ | ||
642 | __CVMX_USB_PIPE_FLAGS_NEED_PING = 1<<18, /**< Used internally to determine if a high speed pipe is in the ping state. Do not use */ | ||
643 | } cvmx_usb_pipe_flags_t; | ||
644 | |||
645 | /** | ||
646 | * Return the number of USB ports supported by this Octeon | ||
647 | * chip. If the chip doesn't support USB, or is not supported | ||
648 | * by this API, a zero will be returned. Most Octeon chips | ||
649 | * support one usb port, but some support two ports. | ||
650 | * cvmx_usb_initialize() must be called on independent | ||
651 | * cvmx_usb_state_t structures. | ||
652 | * | ||
653 | * @return Number of port, zero if usb isn't supported | ||
654 | */ | ||
655 | extern int cvmx_usb_get_num_ports(void); | ||
656 | |||
657 | /** | ||
658 | * Initialize a USB port for use. This must be called before any | ||
659 | * other access to the Octeon USB port is made. The port starts | ||
660 | * off in the disabled state. | ||
661 | * | ||
662 | * @param state Pointer to an empty cvmx_usb_state_t structure | ||
663 | * that will be populated by the initialize call. | ||
664 | * This structure is then passed to all other USB | ||
665 | * functions. | ||
666 | * @param usb_port_number | ||
667 | * Which Octeon USB port to initialize. | ||
668 | * @param flags Flags to control hardware initialization. See | ||
669 | * cvmx_usb_initialize_flags_t for the flag | ||
670 | * definitions. Some flags are mandatory. | ||
671 | * | ||
672 | * @return CVMX_USB_SUCCESS or a negative error code defined in | ||
673 | * cvmx_usb_status_t. | ||
674 | */ | ||
675 | extern cvmx_usb_status_t cvmx_usb_initialize(cvmx_usb_state_t *state, | ||
676 | int usb_port_number, | ||
677 | cvmx_usb_initialize_flags_t flags); | ||
678 | |||
679 | /** | ||
680 | * Shutdown a USB port after a call to cvmx_usb_initialize(). | ||
681 | * The port should be disabled with all pipes closed when this | ||
682 | * function is called. | ||
683 | * | ||
684 | * @param state USB device state populated by | ||
685 | * cvmx_usb_initialize(). | ||
686 | * | ||
687 | * @return CVMX_USB_SUCCESS or a negative error code defined in | ||
688 | * cvmx_usb_status_t. | ||
689 | */ | ||
690 | extern cvmx_usb_status_t cvmx_usb_shutdown(cvmx_usb_state_t *state); | ||
691 | |||
692 | /** | ||
693 | * Enable a USB port. After this call succeeds, the USB port is | ||
694 | * online and servicing requests. | ||
695 | * | ||
696 | * @param state USB device state populated by | ||
697 | * cvmx_usb_initialize(). | ||
698 | * | ||
699 | * @return CVMX_USB_SUCCESS or a negative error code defined in | ||
700 | * cvmx_usb_status_t. | ||
701 | */ | ||
702 | extern cvmx_usb_status_t cvmx_usb_enable(cvmx_usb_state_t *state); | ||
703 | |||
704 | /** | ||
705 | * Disable a USB port. After this call the USB port will not | ||
706 | * generate data transfers and will not generate events. | ||
707 | * Transactions in process will fail and call their | ||
708 | * associated callbacks. | ||
709 | * | ||
710 | * @param state USB device state populated by | ||
711 | * cvmx_usb_initialize(). | ||
712 | * | ||
713 | * @return CVMX_USB_SUCCESS or a negative error code defined in | ||
714 | * cvmx_usb_status_t. | ||
715 | */ | ||
716 | extern cvmx_usb_status_t cvmx_usb_disable(cvmx_usb_state_t *state); | ||
717 | |||
718 | /** | ||
719 | * Get the current state of the USB port. Use this call to | ||
720 | * determine if the usb port has anything connected, is enabled, | ||
721 | * or has some sort of error condition. The return value of this | ||
722 | * call has "changed" bits to signal of the value of some fields | ||
723 | * have changed between calls. These "changed" fields are based | ||
724 | * on the last call to cvmx_usb_set_status(). In order to clear | ||
725 | * them, you must update the status through cvmx_usb_set_status(). | ||
726 | * | ||
727 | * @param state USB device state populated by | ||
728 | * cvmx_usb_initialize(). | ||
729 | * | ||
730 | * @return Port status information | ||
731 | */ | ||
732 | extern cvmx_usb_port_status_t cvmx_usb_get_status(cvmx_usb_state_t *state); | ||
733 | |||
734 | /** | ||
735 | * Set the current state of the USB port. The status is used as | ||
736 | * a reference for the "changed" bits returned by | ||
737 | * cvmx_usb_get_status(). Other than serving as a reference, the | ||
738 | * status passed to this function is not used. No fields can be | ||
739 | * changed through this call. | ||
740 | * | ||
741 | * @param state USB device state populated by | ||
742 | * cvmx_usb_initialize(). | ||
743 | * @param port_status | ||
744 | * Port status to set, most like returned by cvmx_usb_get_status() | ||
745 | */ | ||
746 | extern void cvmx_usb_set_status(cvmx_usb_state_t *state, cvmx_usb_port_status_t port_status); | ||
747 | |||
748 | /** | ||
749 | * Open a virtual pipe between the host and a USB device. A pipe | ||
750 | * must be opened before data can be transferred between a device | ||
751 | * and Octeon. | ||
752 | * | ||
753 | * @param state USB device state populated by | ||
754 | * cvmx_usb_initialize(). | ||
755 | * @param flags Optional pipe flags defined in | ||
756 | * cvmx_usb_pipe_flags_t. | ||
757 | * @param device_addr | ||
758 | * USB device address to open the pipe to | ||
759 | * (0-127). | ||
760 | * @param endpoint_num | ||
761 | * USB endpoint number to open the pipe to | ||
762 | * (0-15). | ||
763 | * @param device_speed | ||
764 | * The speed of the device the pipe is going | ||
765 | * to. This must match the device's speed, | ||
766 | * which may be different than the port speed. | ||
767 | * @param max_packet The maximum packet length the device can | ||
768 | * transmit/receive (low speed=0-8, full | ||
769 | * speed=0-1023, high speed=0-1024). This value | ||
770 | * comes from the standard endpoint descriptor | ||
771 | * field wMaxPacketSize bits <10:0>. | ||
772 | * @param transfer_type | ||
773 | * The type of transfer this pipe is for. | ||
774 | * @param transfer_dir | ||
775 | * The direction the pipe is in. This is not | ||
776 | * used for control pipes. | ||
777 | * @param interval For ISOCHRONOUS and INTERRUPT transfers, | ||
778 | * this is how often the transfer is scheduled | ||
779 | * for. All other transfers should specify | ||
780 | * zero. The units are in frames (8000/sec at | ||
781 | * high speed, 1000/sec for full speed). | ||
782 | * @param multi_count | ||
783 | * For high speed devices, this is the maximum | ||
784 | * allowed number of packet per microframe. | ||
785 | * Specify zero for non high speed devices. This | ||
786 | * value comes from the standard endpoint descriptor | ||
787 | * field wMaxPacketSize bits <12:11>. | ||
788 | * @param hub_device_addr | ||
789 | * Hub device address this device is connected | ||
790 | * to. Devices connected directly to Octeon | ||
791 | * use zero. This is only used when the device | ||
792 | * is full/low speed behind a high speed hub. | ||
793 | * The address will be of the high speed hub, | ||
794 | * not and full speed hubs after it. | ||
795 | * @param hub_port Which port on the hub the device is | ||
796 | * connected. Use zero for devices connected | ||
797 | * directly to Octeon. Like hub_device_addr, | ||
798 | * this is only used for full/low speed | ||
799 | * devices behind a high speed hub. | ||
800 | * | ||
801 | * @return A non negative value is a pipe handle. Negative | ||
802 | * values are failure codes from cvmx_usb_status_t. | ||
803 | */ | ||
804 | extern int cvmx_usb_open_pipe(cvmx_usb_state_t *state, | ||
805 | cvmx_usb_pipe_flags_t flags, | ||
806 | int device_addr, int endpoint_num, | ||
807 | cvmx_usb_speed_t device_speed, int max_packet, | ||
808 | cvmx_usb_transfer_t transfer_type, | ||
809 | cvmx_usb_direction_t transfer_dir, int interval, | ||
810 | int multi_count, int hub_device_addr, | ||
811 | int hub_port); | ||
812 | |||
813 | /** | ||
814 | * Call to submit a USB Bulk transfer to a pipe. | ||
815 | * | ||
816 | * @param state USB device state populated by | ||
817 | * cvmx_usb_initialize(). | ||
818 | * @param pipe_handle | ||
819 | * Handle to the pipe for the transfer. | ||
820 | * @param buffer Physical address of the data buffer in | ||
821 | * memory. Note that this is NOT A POINTER, but | ||
822 | * the full 64bit physical address of the | ||
823 | * buffer. This may be zero if buffer_length is | ||
824 | * zero. | ||
825 | * @param buffer_length | ||
826 | * Length of buffer in bytes. | ||
827 | * @param callback Function to call when this transaction | ||
828 | * completes. If the return value of this | ||
829 | * function isn't an error, then this function | ||
830 | * is guaranteed to be called when the | ||
831 | * transaction completes. If this parameter is | ||
832 | * NULL, then the generic callback registered | ||
833 | * through cvmx_usb_register_callback is | ||
834 | * called. If both are NULL, then there is no | ||
835 | * way to know when a transaction completes. | ||
836 | * @param user_data User supplied data returned when the | ||
837 | * callback is called. This is only used if | ||
838 | * callback in not NULL. | ||
839 | * | ||
840 | * @return A submitted transaction handle or negative on | ||
841 | * failure. Negative values are failure codes from | ||
842 | * cvmx_usb_status_t. | ||
843 | */ | ||
844 | extern int cvmx_usb_submit_bulk(cvmx_usb_state_t *state, int pipe_handle, | ||
845 | uint64_t buffer, int buffer_length, | ||
846 | cvmx_usb_callback_func_t callback, | ||
847 | void *user_data); | ||
848 | |||
849 | /** | ||
850 | * Call to submit a USB Interrupt transfer to a pipe. | ||
851 | * | ||
852 | * @param state USB device state populated by | ||
853 | * cvmx_usb_initialize(). | ||
854 | * @param pipe_handle | ||
855 | * Handle to the pipe for the transfer. | ||
856 | * @param buffer Physical address of the data buffer in | ||
857 | * memory. Note that this is NOT A POINTER, but | ||
858 | * the full 64bit physical address of the | ||
859 | * buffer. This may be zero if buffer_length is | ||
860 | * zero. | ||
861 | * @param buffer_length | ||
862 | * Length of buffer in bytes. | ||
863 | * @param callback Function to call when this transaction | ||
864 | * completes. If the return value of this | ||
865 | * function isn't an error, then this function | ||
866 | * is guaranteed to be called when the | ||
867 | * transaction completes. If this parameter is | ||
868 | * NULL, then the generic callback registered | ||
869 | * through cvmx_usb_register_callback is | ||
870 | * called. If both are NULL, then there is no | ||
871 | * way to know when a transaction completes. | ||
872 | * @param user_data User supplied data returned when the | ||
873 | * callback is called. This is only used if | ||
874 | * callback in not NULL. | ||
875 | * | ||
876 | * @return A submitted transaction handle or negative on | ||
877 | * failure. Negative values are failure codes from | ||
878 | * cvmx_usb_status_t. | ||
879 | */ | ||
880 | extern int cvmx_usb_submit_interrupt(cvmx_usb_state_t *state, int pipe_handle, | ||
881 | uint64_t buffer, int buffer_length, | ||
882 | cvmx_usb_callback_func_t callback, | ||
883 | void *user_data); | ||
884 | |||
885 | /** | ||
886 | * Call to submit a USB Control transfer to a pipe. | ||
887 | * | ||
888 | * @param state USB device state populated by | ||
889 | * cvmx_usb_initialize(). | ||
890 | * @param pipe_handle | ||
891 | * Handle to the pipe for the transfer. | ||
892 | * @param control_header | ||
893 | * USB 8 byte control header physical address. | ||
894 | * Note that this is NOT A POINTER, but the | ||
895 | * full 64bit physical address of the buffer. | ||
896 | * @param buffer Physical address of the data buffer in | ||
897 | * memory. Note that this is NOT A POINTER, but | ||
898 | * the full 64bit physical address of the | ||
899 | * buffer. This may be zero if buffer_length is | ||
900 | * zero. | ||
901 | * @param buffer_length | ||
902 | * Length of buffer in bytes. | ||
903 | * @param callback Function to call when this transaction | ||
904 | * completes. If the return value of this | ||
905 | * function isn't an error, then this function | ||
906 | * is guaranteed to be called when the | ||
907 | * transaction completes. If this parameter is | ||
908 | * NULL, then the generic callback registered | ||
909 | * through cvmx_usb_register_callback is | ||
910 | * called. If both are NULL, then there is no | ||
911 | * way to know when a transaction completes. | ||
912 | * @param user_data User supplied data returned when the | ||
913 | * callback is called. This is only used if | ||
914 | * callback in not NULL. | ||
915 | * | ||
916 | * @return A submitted transaction handle or negative on | ||
917 | * failure. Negative values are failure codes from | ||
918 | * cvmx_usb_status_t. | ||
919 | */ | ||
920 | extern int cvmx_usb_submit_control(cvmx_usb_state_t *state, int pipe_handle, | ||
921 | uint64_t control_header, | ||
922 | uint64_t buffer, int buffer_length, | ||
923 | cvmx_usb_callback_func_t callback, | ||
924 | void *user_data); | ||
925 | |||
926 | /** | ||
927 | * Flags to pass the cvmx_usb_submit_isochronous() function. | ||
928 | */ | ||
929 | typedef enum | ||
930 | { | ||
931 | CVMX_USB_ISOCHRONOUS_FLAGS_ALLOW_SHORT = 1<<0, /**< Do not return an error if a transfer is less than the maximum packet size of the device */ | ||
932 | CVMX_USB_ISOCHRONOUS_FLAGS_ASAP = 1<<1, /**< Schedule the transaction as soon as possible */ | ||
933 | } cvmx_usb_isochronous_flags_t; | ||
934 | |||
935 | /** | ||
936 | * Call to submit a USB Isochronous transfer to a pipe. | ||
937 | * | ||
938 | * @param state USB device state populated by | ||
939 | * cvmx_usb_initialize(). | ||
940 | * @param pipe_handle | ||
941 | * Handle to the pipe for the transfer. | ||
942 | * @param start_frame | ||
943 | * Number of frames into the future to schedule | ||
944 | * this transaction. | ||
945 | * @param flags Flags to control the transfer. See | ||
946 | * cvmx_usb_isochronous_flags_t for the flag | ||
947 | * definitions. | ||
948 | * @param number_packets | ||
949 | * Number of sequential packets to transfer. | ||
950 | * "packets" is a pointer to an array of this | ||
951 | * many packet structures. | ||
952 | * @param packets Description of each transfer packet as | ||
953 | * defined by cvmx_usb_iso_packet_t. The array | ||
954 | * pointed to here must stay valid until the | ||
955 | * complete callback is called. | ||
956 | * @param buffer Physical address of the data buffer in | ||
957 | * memory. Note that this is NOT A POINTER, but | ||
958 | * the full 64bit physical address of the | ||
959 | * buffer. This may be zero if buffer_length is | ||
960 | * zero. | ||
961 | * @param buffer_length | ||
962 | * Length of buffer in bytes. | ||
963 | * @param callback Function to call when this transaction | ||
964 | * completes. If the return value of this | ||
965 | * function isn't an error, then this function | ||
966 | * is guaranteed to be called when the | ||
967 | * transaction completes. If this parameter is | ||
968 | * NULL, then the generic callback registered | ||
969 | * through cvmx_usb_register_callback is | ||
970 | * called. If both are NULL, then there is no | ||
971 | * way to know when a transaction completes. | ||
972 | * @param user_data User supplied data returned when the | ||
973 | * callback is called. This is only used if | ||
974 | * callback in not NULL. | ||
975 | * | ||
976 | * @return A submitted transaction handle or negative on | ||
977 | * failure. Negative values are failure codes from | ||
978 | * cvmx_usb_status_t. | ||
979 | */ | ||
980 | extern int cvmx_usb_submit_isochronous(cvmx_usb_state_t *state, int pipe_handle, | ||
981 | int start_frame, int flags, | ||
982 | int number_packets, | ||
983 | cvmx_usb_iso_packet_t packets[], | ||
984 | uint64_t buffer, int buffer_length, | ||
985 | cvmx_usb_callback_func_t callback, | ||
986 | void *user_data); | ||
987 | |||
988 | /** | ||
989 | * Cancel one outstanding request in a pipe. Canceling a request | ||
990 | * can fail if the transaction has already completed before cancel | ||
991 | * is called. Even after a successful cancel call, it may take | ||
992 | * a frame or two for the cvmx_usb_poll() function to call the | ||
993 | * associated callback. | ||
994 | * | ||
995 | * @param state USB device state populated by | ||
996 | * cvmx_usb_initialize(). | ||
997 | * @param pipe_handle | ||
998 | * Pipe handle to cancel requests in. | ||
999 | * @param submit_handle | ||
1000 | * Handle to transaction to cancel, returned by the submit function. | ||
1001 | * | ||
1002 | * @return CVMX_USB_SUCCESS or a negative error code defined in | ||
1003 | * cvmx_usb_status_t. | ||
1004 | */ | ||
1005 | extern cvmx_usb_status_t cvmx_usb_cancel(cvmx_usb_state_t *state, | ||
1006 | int pipe_handle, int submit_handle); | ||
1007 | |||
1008 | |||
1009 | /** | ||
1010 | * Cancel all outstanding requests in a pipe. Logically all this | ||
1011 | * does is call cvmx_usb_cancel() in a loop. | ||
1012 | * | ||
1013 | * @param state USB device state populated by | ||
1014 | * cvmx_usb_initialize(). | ||
1015 | * @param pipe_handle | ||
1016 | * Pipe handle to cancel requests in. | ||
1017 | * | ||
1018 | * @return CVMX_USB_SUCCESS or a negative error code defined in | ||
1019 | * cvmx_usb_status_t. | ||
1020 | */ | ||
1021 | extern cvmx_usb_status_t cvmx_usb_cancel_all(cvmx_usb_state_t *state, | ||
1022 | int pipe_handle); | ||
1023 | |||
1024 | /** | ||
1025 | * Close a pipe created with cvmx_usb_open_pipe(). | ||
1026 | * | ||
1027 | * @param state USB device state populated by | ||
1028 | * cvmx_usb_initialize(). | ||
1029 | * @param pipe_handle | ||
1030 | * Pipe handle to close. | ||
1031 | * | ||
1032 | * @return CVMX_USB_SUCCESS or a negative error code defined in | ||
1033 | * cvmx_usb_status_t. CVMX_USB_BUSY is returned if the | ||
1034 | * pipe has outstanding transfers. | ||
1035 | */ | ||
1036 | extern cvmx_usb_status_t cvmx_usb_close_pipe(cvmx_usb_state_t *state, | ||
1037 | int pipe_handle); | ||
1038 | |||
1039 | /** | ||
1040 | * Register a function to be called when various USB events occur. | ||
1041 | * | ||
1042 | * @param state USB device state populated by | ||
1043 | * cvmx_usb_initialize(). | ||
1044 | * @param reason Which event to register for. | ||
1045 | * @param callback Function to call when the event occurs. | ||
1046 | * @param user_data User data parameter to the function. | ||
1047 | * | ||
1048 | * @return CVMX_USB_SUCCESS or a negative error code defined in | ||
1049 | * cvmx_usb_status_t. | ||
1050 | */ | ||
1051 | extern cvmx_usb_status_t cvmx_usb_register_callback(cvmx_usb_state_t *state, | ||
1052 | cvmx_usb_callback_t reason, | ||
1053 | cvmx_usb_callback_func_t callback, | ||
1054 | void *user_data); | ||
1055 | |||
1056 | /** | ||
1057 | * Get the current USB protocol level frame number. The frame | ||
1058 | * number is always in the range of 0-0x7ff. | ||
1059 | * | ||
1060 | * @param state USB device state populated by | ||
1061 | * cvmx_usb_initialize(). | ||
1062 | * | ||
1063 | * @return USB frame number | ||
1064 | */ | ||
1065 | extern int cvmx_usb_get_frame_number(cvmx_usb_state_t *state); | ||
1066 | |||
1067 | /** | ||
1068 | * Poll the USB block for status and call all needed callback | ||
1069 | * handlers. This function is meant to be called in the interrupt | ||
1070 | * handler for the USB controller. It can also be called | ||
1071 | * periodically in a loop for non-interrupt based operation. | ||
1072 | * | ||
1073 | * @param state USB device state populated by | ||
1074 | * cvmx_usb_initialize(). | ||
1075 | * | ||
1076 | * @return CVMX_USB_SUCCESS or a negative error code defined in | ||
1077 | * cvmx_usb_status_t. | ||
1078 | */ | ||
1079 | extern cvmx_usb_status_t cvmx_usb_poll(cvmx_usb_state_t *state); | ||
1080 | |||
1081 | #ifdef __cplusplus | ||
1082 | } | ||
1083 | #endif | ||
1084 | |||
1085 | #endif /* __CVMX_USB_H__ */ | ||
diff --git a/drivers/staging/octeon-usb/cvmx-usbcx-defs.h b/drivers/staging/octeon-usb/cvmx-usbcx-defs.h new file mode 100644 index 000000000000..e3ae545b725c --- /dev/null +++ b/drivers/staging/octeon-usb/cvmx-usbcx-defs.h | |||
@@ -0,0 +1,3086 @@ | |||
1 | /***********************license start*************** | ||
2 | * Copyright (c) 2003-2010 Cavium Networks (support@cavium.com). All rights | ||
3 | * reserved. | ||
4 | * | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions are | ||
8 | * met: | ||
9 | * | ||
10 | * * Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * | ||
13 | * * Redistributions in binary form must reproduce the above | ||
14 | * copyright notice, this list of conditions and the following | ||
15 | * disclaimer in the documentation and/or other materials provided | ||
16 | * with the distribution. | ||
17 | |||
18 | * * Neither the name of Cavium Networks nor the names of | ||
19 | * its contributors may be used to endorse or promote products | ||
20 | * derived from this software without specific prior written | ||
21 | * permission. | ||
22 | |||
23 | * This Software, including technical data, may be subject to U.S. export control | ||
24 | * laws, including the U.S. Export Administration Act and its associated | ||
25 | * regulations, and may be subject to export or import regulations in other | ||
26 | * countries. | ||
27 | |||
28 | * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" | ||
29 | * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR | ||
30 | * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO | ||
31 | * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR | ||
32 | * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM | ||
33 | * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, | ||
34 | * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF | ||
35 | * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR | ||
36 | * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR | ||
37 | * PERFORMANCE OF THE SOFTWARE LIES WITH YOU. | ||
38 | ***********************license end**************************************/ | ||
39 | |||
40 | |||
41 | /** | ||
42 | * cvmx-usbcx-defs.h | ||
43 | * | ||
44 | * Configuration and status register (CSR) type definitions for | ||
45 | * Octeon usbcx. | ||
46 | * | ||
47 | * This file is auto generated. Do not edit. | ||
48 | * | ||
49 | * <hr>$Revision$<hr> | ||
50 | * | ||
51 | */ | ||
52 | #ifndef __CVMX_USBCX_TYPEDEFS_H__ | ||
53 | #define __CVMX_USBCX_TYPEDEFS_H__ | ||
54 | |||
55 | #define CVMX_USBCX_DAINT(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000818ull) + ((block_id) & 1) * 0x100000000000ull) | ||
56 | #define CVMX_USBCX_DAINTMSK(block_id) (CVMX_ADD_IO_SEG(0x00016F001000081Cull) + ((block_id) & 1) * 0x100000000000ull) | ||
57 | #define CVMX_USBCX_DCFG(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000800ull) + ((block_id) & 1) * 0x100000000000ull) | ||
58 | #define CVMX_USBCX_DCTL(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000804ull) + ((block_id) & 1) * 0x100000000000ull) | ||
59 | #define CVMX_USBCX_DIEPCTLX(offset, block_id) (CVMX_ADD_IO_SEG(0x00016F0010000900ull) + (((offset) & 7) + ((block_id) & 1) * 0x8000000000ull) * 32) | ||
60 | #define CVMX_USBCX_DIEPINTX(offset, block_id) (CVMX_ADD_IO_SEG(0x00016F0010000908ull) + (((offset) & 7) + ((block_id) & 1) * 0x8000000000ull) * 32) | ||
61 | #define CVMX_USBCX_DIEPMSK(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000810ull) + ((block_id) & 1) * 0x100000000000ull) | ||
62 | #define CVMX_USBCX_DIEPTSIZX(offset, block_id) (CVMX_ADD_IO_SEG(0x00016F0010000910ull) + (((offset) & 7) + ((block_id) & 1) * 0x8000000000ull) * 32) | ||
63 | #define CVMX_USBCX_DOEPCTLX(offset, block_id) (CVMX_ADD_IO_SEG(0x00016F0010000B00ull) + (((offset) & 7) + ((block_id) & 1) * 0x8000000000ull) * 32) | ||
64 | #define CVMX_USBCX_DOEPINTX(offset, block_id) (CVMX_ADD_IO_SEG(0x00016F0010000B08ull) + (((offset) & 7) + ((block_id) & 1) * 0x8000000000ull) * 32) | ||
65 | #define CVMX_USBCX_DOEPMSK(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000814ull) + ((block_id) & 1) * 0x100000000000ull) | ||
66 | #define CVMX_USBCX_DOEPTSIZX(offset, block_id) (CVMX_ADD_IO_SEG(0x00016F0010000B10ull) + (((offset) & 7) + ((block_id) & 1) * 0x8000000000ull) * 32) | ||
67 | #define CVMX_USBCX_DPTXFSIZX(offset, block_id) (CVMX_ADD_IO_SEG(0x00016F0010000100ull) + (((offset) & 7) + ((block_id) & 1) * 0x40000000000ull) * 4) | ||
68 | #define CVMX_USBCX_DSTS(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000808ull) + ((block_id) & 1) * 0x100000000000ull) | ||
69 | #define CVMX_USBCX_DTKNQR1(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000820ull) + ((block_id) & 1) * 0x100000000000ull) | ||
70 | #define CVMX_USBCX_DTKNQR2(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000824ull) + ((block_id) & 1) * 0x100000000000ull) | ||
71 | #define CVMX_USBCX_DTKNQR3(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000830ull) + ((block_id) & 1) * 0x100000000000ull) | ||
72 | #define CVMX_USBCX_DTKNQR4(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000834ull) + ((block_id) & 1) * 0x100000000000ull) | ||
73 | #define CVMX_USBCX_GAHBCFG(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000008ull) + ((block_id) & 1) * 0x100000000000ull) | ||
74 | #define CVMX_USBCX_GHWCFG1(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000044ull) + ((block_id) & 1) * 0x100000000000ull) | ||
75 | #define CVMX_USBCX_GHWCFG2(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000048ull) + ((block_id) & 1) * 0x100000000000ull) | ||
76 | #define CVMX_USBCX_GHWCFG3(block_id) (CVMX_ADD_IO_SEG(0x00016F001000004Cull) + ((block_id) & 1) * 0x100000000000ull) | ||
77 | #define CVMX_USBCX_GHWCFG4(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000050ull) + ((block_id) & 1) * 0x100000000000ull) | ||
78 | #define CVMX_USBCX_GINTMSK(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000018ull) + ((block_id) & 1) * 0x100000000000ull) | ||
79 | #define CVMX_USBCX_GINTSTS(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000014ull) + ((block_id) & 1) * 0x100000000000ull) | ||
80 | #define CVMX_USBCX_GNPTXFSIZ(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000028ull) + ((block_id) & 1) * 0x100000000000ull) | ||
81 | #define CVMX_USBCX_GNPTXSTS(block_id) (CVMX_ADD_IO_SEG(0x00016F001000002Cull) + ((block_id) & 1) * 0x100000000000ull) | ||
82 | #define CVMX_USBCX_GOTGCTL(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000000ull) + ((block_id) & 1) * 0x100000000000ull) | ||
83 | #define CVMX_USBCX_GOTGINT(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000004ull) + ((block_id) & 1) * 0x100000000000ull) | ||
84 | #define CVMX_USBCX_GRSTCTL(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000010ull) + ((block_id) & 1) * 0x100000000000ull) | ||
85 | #define CVMX_USBCX_GRXFSIZ(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000024ull) + ((block_id) & 1) * 0x100000000000ull) | ||
86 | #define CVMX_USBCX_GRXSTSPD(block_id) (CVMX_ADD_IO_SEG(0x00016F0010040020ull) + ((block_id) & 1) * 0x100000000000ull) | ||
87 | #define CVMX_USBCX_GRXSTSPH(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000020ull) + ((block_id) & 1) * 0x100000000000ull) | ||
88 | #define CVMX_USBCX_GRXSTSRD(block_id) (CVMX_ADD_IO_SEG(0x00016F001004001Cull) + ((block_id) & 1) * 0x100000000000ull) | ||
89 | #define CVMX_USBCX_GRXSTSRH(block_id) (CVMX_ADD_IO_SEG(0x00016F001000001Cull) + ((block_id) & 1) * 0x100000000000ull) | ||
90 | #define CVMX_USBCX_GSNPSID(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000040ull) + ((block_id) & 1) * 0x100000000000ull) | ||
91 | #define CVMX_USBCX_GUSBCFG(block_id) (CVMX_ADD_IO_SEG(0x00016F001000000Cull) + ((block_id) & 1) * 0x100000000000ull) | ||
92 | #define CVMX_USBCX_HAINT(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000414ull) + ((block_id) & 1) * 0x100000000000ull) | ||
93 | #define CVMX_USBCX_HAINTMSK(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000418ull) + ((block_id) & 1) * 0x100000000000ull) | ||
94 | #define CVMX_USBCX_HCCHARX(offset, block_id) (CVMX_ADD_IO_SEG(0x00016F0010000500ull) + (((offset) & 7) + ((block_id) & 1) * 0x8000000000ull) * 32) | ||
95 | #define CVMX_USBCX_HCFG(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000400ull) + ((block_id) & 1) * 0x100000000000ull) | ||
96 | #define CVMX_USBCX_HCINTMSKX(offset, block_id) (CVMX_ADD_IO_SEG(0x00016F001000050Cull) + (((offset) & 7) + ((block_id) & 1) * 0x8000000000ull) * 32) | ||
97 | #define CVMX_USBCX_HCINTX(offset, block_id) (CVMX_ADD_IO_SEG(0x00016F0010000508ull) + (((offset) & 7) + ((block_id) & 1) * 0x8000000000ull) * 32) | ||
98 | #define CVMX_USBCX_HCSPLTX(offset, block_id) (CVMX_ADD_IO_SEG(0x00016F0010000504ull) + (((offset) & 7) + ((block_id) & 1) * 0x8000000000ull) * 32) | ||
99 | #define CVMX_USBCX_HCTSIZX(offset, block_id) (CVMX_ADD_IO_SEG(0x00016F0010000510ull) + (((offset) & 7) + ((block_id) & 1) * 0x8000000000ull) * 32) | ||
100 | #define CVMX_USBCX_HFIR(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000404ull) + ((block_id) & 1) * 0x100000000000ull) | ||
101 | #define CVMX_USBCX_HFNUM(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000408ull) + ((block_id) & 1) * 0x100000000000ull) | ||
102 | #define CVMX_USBCX_HPRT(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000440ull) + ((block_id) & 1) * 0x100000000000ull) | ||
103 | #define CVMX_USBCX_HPTXFSIZ(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000100ull) + ((block_id) & 1) * 0x100000000000ull) | ||
104 | #define CVMX_USBCX_HPTXSTS(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000410ull) + ((block_id) & 1) * 0x100000000000ull) | ||
105 | #define CVMX_USBCX_NPTXDFIFOX(offset, block_id) (CVMX_ADD_IO_SEG(0x00016F0010001000ull) + (((offset) & 7) + ((block_id) & 1) * 0x100000000ull) * 4096) | ||
106 | #define CVMX_USBCX_PCGCCTL(block_id) (CVMX_ADD_IO_SEG(0x00016F0010000E00ull) + ((block_id) & 1) * 0x100000000000ull) | ||
107 | |||
108 | /** | ||
109 | * cvmx_usbc#_daint | ||
110 | * | ||
111 | * Device All Endpoints Interrupt Register (DAINT) | ||
112 | * | ||
113 | * When a significant event occurs on an endpoint, a Device All Endpoints Interrupt register | ||
114 | * interrupts the application using the Device OUT Endpoints Interrupt bit or Device IN Endpoints | ||
115 | * Interrupt bit of the Core Interrupt register (GINTSTS.OEPInt or GINTSTS.IEPInt, respectively). | ||
116 | * There is one interrupt bit per endpoint, up to a maximum of 16 bits for OUT endpoints and 16 | ||
117 | * bits for IN endpoints. For a bidirectional endpoint, the corresponding IN and OUT interrupt | ||
118 | * bits are used. Bits in this register are set and cleared when the application sets and clears | ||
119 | * bits in the corresponding Device Endpoint-n Interrupt register (DIEPINTn/DOEPINTn). | ||
120 | */ | ||
121 | union cvmx_usbcx_daint | ||
122 | { | ||
123 | uint32_t u32; | ||
124 | struct cvmx_usbcx_daint_s | ||
125 | { | ||
126 | uint32_t outepint : 16; /**< OUT Endpoint Interrupt Bits (OutEPInt) | ||
127 | One bit per OUT endpoint: | ||
128 | Bit 16 for OUT endpoint 0, bit 31 for OUT endpoint 15 */ | ||
129 | uint32_t inepint : 16; /**< IN Endpoint Interrupt Bits (InEpInt) | ||
130 | One bit per IN Endpoint: | ||
131 | Bit 0 for IN endpoint 0, bit 15 for endpoint 15 */ | ||
132 | } s; | ||
133 | struct cvmx_usbcx_daint_s cn30xx; | ||
134 | struct cvmx_usbcx_daint_s cn31xx; | ||
135 | struct cvmx_usbcx_daint_s cn50xx; | ||
136 | struct cvmx_usbcx_daint_s cn52xx; | ||
137 | struct cvmx_usbcx_daint_s cn52xxp1; | ||
138 | struct cvmx_usbcx_daint_s cn56xx; | ||
139 | struct cvmx_usbcx_daint_s cn56xxp1; | ||
140 | }; | ||
141 | typedef union cvmx_usbcx_daint cvmx_usbcx_daint_t; | ||
142 | |||
143 | /** | ||
144 | * cvmx_usbc#_daintmsk | ||
145 | * | ||
146 | * Device All Endpoints Interrupt Mask Register (DAINTMSK) | ||
147 | * | ||
148 | * The Device Endpoint Interrupt Mask register works with the Device Endpoint Interrupt register | ||
149 | * to interrupt the application when an event occurs on a device endpoint. However, the Device | ||
150 | * All Endpoints Interrupt (DAINT) register bit corresponding to that interrupt will still be set. | ||
151 | * Mask Interrupt: 1'b0 Unmask Interrupt: 1'b1 | ||
152 | */ | ||
153 | union cvmx_usbcx_daintmsk | ||
154 | { | ||
155 | uint32_t u32; | ||
156 | struct cvmx_usbcx_daintmsk_s | ||
157 | { | ||
158 | uint32_t outepmsk : 16; /**< OUT EP Interrupt Mask Bits (OutEpMsk) | ||
159 | One per OUT Endpoint: | ||
160 | Bit 16 for OUT EP 0, bit 31 for OUT EP 15 */ | ||
161 | uint32_t inepmsk : 16; /**< IN EP Interrupt Mask Bits (InEpMsk) | ||
162 | One bit per IN Endpoint: | ||
163 | Bit 0 for IN EP 0, bit 15 for IN EP 15 */ | ||
164 | } s; | ||
165 | struct cvmx_usbcx_daintmsk_s cn30xx; | ||
166 | struct cvmx_usbcx_daintmsk_s cn31xx; | ||
167 | struct cvmx_usbcx_daintmsk_s cn50xx; | ||
168 | struct cvmx_usbcx_daintmsk_s cn52xx; | ||
169 | struct cvmx_usbcx_daintmsk_s cn52xxp1; | ||
170 | struct cvmx_usbcx_daintmsk_s cn56xx; | ||
171 | struct cvmx_usbcx_daintmsk_s cn56xxp1; | ||
172 | }; | ||
173 | typedef union cvmx_usbcx_daintmsk cvmx_usbcx_daintmsk_t; | ||
174 | |||
175 | /** | ||
176 | * cvmx_usbc#_dcfg | ||
177 | * | ||
178 | * Device Configuration Register (DCFG) | ||
179 | * | ||
180 | * This register configures the core in Device mode after power-on or after certain control | ||
181 | * commands or enumeration. Do not make changes to this register after initial programming. | ||
182 | */ | ||
183 | union cvmx_usbcx_dcfg | ||
184 | { | ||
185 | uint32_t u32; | ||
186 | struct cvmx_usbcx_dcfg_s | ||
187 | { | ||
188 | uint32_t reserved_23_31 : 9; | ||
189 | uint32_t epmiscnt : 5; /**< IN Endpoint Mismatch Count (EPMisCnt) | ||
190 | The application programs this filed with a count that determines | ||
191 | when the core generates an Endpoint Mismatch interrupt | ||
192 | (GINTSTS.EPMis). The core loads this value into an internal | ||
193 | counter and decrements it. The counter is reloaded whenever | ||
194 | there is a match or when the counter expires. The width of this | ||
195 | counter depends on the depth of the Token Queue. */ | ||
196 | uint32_t reserved_13_17 : 5; | ||
197 | uint32_t perfrint : 2; /**< Periodic Frame Interval (PerFrInt) | ||
198 | Indicates the time within a (micro)frame at which the application | ||
199 | must be notified using the End Of Periodic Frame Interrupt. This | ||
200 | can be used to determine if all the isochronous traffic for that | ||
201 | (micro)frame is complete. | ||
202 | * 2'b00: 80% of the (micro)frame interval | ||
203 | * 2'b01: 85% | ||
204 | * 2'b10: 90% | ||
205 | * 2'b11: 95% */ | ||
206 | uint32_t devaddr : 7; /**< Device Address (DevAddr) | ||
207 | The application must program this field after every SetAddress | ||
208 | control command. */ | ||
209 | uint32_t reserved_3_3 : 1; | ||
210 | uint32_t nzstsouthshk : 1; /**< Non-Zero-Length Status OUT Handshake (NZStsOUTHShk) | ||
211 | The application can use this field to select the handshake the | ||
212 | core sends on receiving a nonzero-length data packet during | ||
213 | the OUT transaction of a control transfer's Status stage. | ||
214 | * 1'b1: Send a STALL handshake on a nonzero-length status | ||
215 | OUT transaction and do not send the received OUT packet to | ||
216 | the application. | ||
217 | * 1'b0: Send the received OUT packet to the application (zero- | ||
218 | length or nonzero-length) and send a handshake based on | ||
219 | the NAK and STALL bits for the endpoint in the Device | ||
220 | Endpoint Control register. */ | ||
221 | uint32_t devspd : 2; /**< Device Speed (DevSpd) | ||
222 | Indicates the speed at which the application requires the core to | ||
223 | enumerate, or the maximum speed the application can support. | ||
224 | However, the actual bus speed is determined only after the | ||
225 | chirp sequence is completed, and is based on the speed of the | ||
226 | USB host to which the core is connected. See "Device | ||
227 | Initialization" on page 249 for details. | ||
228 | * 2'b00: High speed (USB 2.0 PHY clock is 30 MHz or 60 MHz) | ||
229 | * 2'b01: Full speed (USB 2.0 PHY clock is 30 MHz or 60 MHz) | ||
230 | * 2'b10: Low speed (USB 1.1 transceiver clock is 6 MHz). If | ||
231 | you select 6 MHz LS mode, you must do a soft reset. | ||
232 | * 2'b11: Full speed (USB 1.1 transceiver clock is 48 MHz) */ | ||
233 | } s; | ||
234 | struct cvmx_usbcx_dcfg_s cn30xx; | ||
235 | struct cvmx_usbcx_dcfg_s cn31xx; | ||
236 | struct cvmx_usbcx_dcfg_s cn50xx; | ||
237 | struct cvmx_usbcx_dcfg_s cn52xx; | ||
238 | struct cvmx_usbcx_dcfg_s cn52xxp1; | ||
239 | struct cvmx_usbcx_dcfg_s cn56xx; | ||
240 | struct cvmx_usbcx_dcfg_s cn56xxp1; | ||
241 | }; | ||
242 | typedef union cvmx_usbcx_dcfg cvmx_usbcx_dcfg_t; | ||
243 | |||
244 | /** | ||
245 | * cvmx_usbc#_dctl | ||
246 | * | ||
247 | * Device Control Register (DCTL) | ||
248 | * | ||
249 | */ | ||
250 | union cvmx_usbcx_dctl | ||
251 | { | ||
252 | uint32_t u32; | ||
253 | struct cvmx_usbcx_dctl_s | ||
254 | { | ||
255 | uint32_t reserved_12_31 : 20; | ||
256 | uint32_t pwronprgdone : 1; /**< Power-On Programming Done (PWROnPrgDone) | ||
257 | The application uses this bit to indicate that register | ||
258 | programming is completed after a wake-up from Power Down | ||
259 | mode. For more information, see "Device Mode Suspend and | ||
260 | Resume With Partial Power-Down" on page 357. */ | ||
261 | uint32_t cgoutnak : 1; /**< Clear Global OUT NAK (CGOUTNak) | ||
262 | A write to this field clears the Global OUT NAK. */ | ||
263 | uint32_t sgoutnak : 1; /**< Set Global OUT NAK (SGOUTNak) | ||
264 | A write to this field sets the Global OUT NAK. | ||
265 | The application uses this bit to send a NAK handshake on all | ||
266 | OUT endpoints. | ||
267 | The application should set the this bit only after making sure | ||
268 | that the Global OUT NAK Effective bit in the Core Interrupt | ||
269 | Register (GINTSTS.GOUTNakEff) is cleared. */ | ||
270 | uint32_t cgnpinnak : 1; /**< Clear Global Non-Periodic IN NAK (CGNPInNak) | ||
271 | A write to this field clears the Global Non-Periodic IN NAK. */ | ||
272 | uint32_t sgnpinnak : 1; /**< Set Global Non-Periodic IN NAK (SGNPInNak) | ||
273 | A write to this field sets the Global Non-Periodic IN NAK.The | ||
274 | application uses this bit to send a NAK handshake on all non- | ||
275 | periodic IN endpoints. The core can also set this bit when a | ||
276 | timeout condition is detected on a non-periodic endpoint. | ||
277 | The application should set this bit only after making sure that | ||
278 | the Global IN NAK Effective bit in the Core Interrupt Register | ||
279 | (GINTSTS.GINNakEff) is cleared. */ | ||
280 | uint32_t tstctl : 3; /**< Test Control (TstCtl) | ||
281 | * 3'b000: Test mode disabled | ||
282 | * 3'b001: Test_J mode | ||
283 | * 3'b010: Test_K mode | ||
284 | * 3'b011: Test_SE0_NAK mode | ||
285 | * 3'b100: Test_Packet mode | ||
286 | * 3'b101: Test_Force_Enable | ||
287 | * Others: Reserved */ | ||
288 | uint32_t goutnaksts : 1; /**< Global OUT NAK Status (GOUTNakSts) | ||
289 | * 1'b0: A handshake is sent based on the FIFO Status and the | ||
290 | NAK and STALL bit settings. | ||
291 | * 1'b1: No data is written to the RxFIFO, irrespective of space | ||
292 | availability. Sends a NAK handshake on all packets, except | ||
293 | on SETUP transactions. All isochronous OUT packets are | ||
294 | dropped. */ | ||
295 | uint32_t gnpinnaksts : 1; /**< Global Non-Periodic IN NAK Status (GNPINNakSts) | ||
296 | * 1'b0: A handshake is sent out based on the data availability | ||
297 | in the transmit FIFO. | ||
298 | * 1'b1: A NAK handshake is sent out on all non-periodic IN | ||
299 | endpoints, irrespective of the data availability in the transmit | ||
300 | FIFO. */ | ||
301 | uint32_t sftdiscon : 1; /**< Soft Disconnect (SftDiscon) | ||
302 | The application uses this bit to signal the O2P USB core to do a | ||
303 | soft disconnect. As long as this bit is set, the host will not see | ||
304 | that the device is connected, and the device will not receive | ||
305 | signals on the USB. The core stays in the disconnected state | ||
306 | until the application clears this bit. | ||
307 | The minimum duration for which the core must keep this bit set | ||
308 | is specified in Minimum Duration for Soft Disconnect . | ||
309 | * 1'b0: Normal operation. When this bit is cleared after a soft | ||
310 | disconnect, the core drives the phy_opmode_o signal on the | ||
311 | UTMI+ to 2'b00, which generates a device connect event to | ||
312 | the USB host. When the device is reconnected, the USB host | ||
313 | restarts device enumeration. | ||
314 | * 1'b1: The core drives the phy_opmode_o signal on the | ||
315 | UTMI+ to 2'b01, which generates a device disconnect event | ||
316 | to the USB host. */ | ||
317 | uint32_t rmtwkupsig : 1; /**< Remote Wakeup Signaling (RmtWkUpSig) | ||
318 | When the application sets this bit, the core initiates remote | ||
319 | signaling to wake up the USB host.The application must set this | ||
320 | bit to get the core out of Suspended state and must clear this bit | ||
321 | after the core comes out of Suspended state. */ | ||
322 | } s; | ||
323 | struct cvmx_usbcx_dctl_s cn30xx; | ||
324 | struct cvmx_usbcx_dctl_s cn31xx; | ||
325 | struct cvmx_usbcx_dctl_s cn50xx; | ||
326 | struct cvmx_usbcx_dctl_s cn52xx; | ||
327 | struct cvmx_usbcx_dctl_s cn52xxp1; | ||
328 | struct cvmx_usbcx_dctl_s cn56xx; | ||
329 | struct cvmx_usbcx_dctl_s cn56xxp1; | ||
330 | }; | ||
331 | typedef union cvmx_usbcx_dctl cvmx_usbcx_dctl_t; | ||
332 | |||
333 | /** | ||
334 | * cvmx_usbc#_diepctl# | ||
335 | * | ||
336 | * Device IN Endpoint-n Control Register (DIEPCTLn) | ||
337 | * | ||
338 | * The application uses the register to control the behaviour of each logical endpoint other than endpoint 0. | ||
339 | */ | ||
340 | union cvmx_usbcx_diepctlx | ||
341 | { | ||
342 | uint32_t u32; | ||
343 | struct cvmx_usbcx_diepctlx_s | ||
344 | { | ||
345 | uint32_t epena : 1; /**< Endpoint Enable (EPEna) | ||
346 | Indicates that data is ready to be transmitted on the endpoint. | ||
347 | The core clears this bit before setting any of the following | ||
348 | interrupts on this endpoint: | ||
349 | * Endpoint Disabled | ||
350 | * Transfer Completed */ | ||
351 | uint32_t epdis : 1; /**< Endpoint Disable (EPDis) | ||
352 | The application sets this bit to stop transmitting data on an | ||
353 | endpoint, even before the transfer for that endpoint is complete. | ||
354 | The application must wait for the Endpoint Disabled interrupt | ||
355 | before treating the endpoint as disabled. The core clears this bit | ||
356 | before setting the Endpoint Disabled Interrupt. The application | ||
357 | should set this bit only if Endpoint Enable is already set for this | ||
358 | endpoint. */ | ||
359 | uint32_t setd1pid : 1; /**< For Interrupt/BULK enpoints: | ||
360 | Set DATA1 PID (SetD1PID) | ||
361 | Writing to this field sets the Endpoint Data Pid (DPID) field in | ||
362 | this register to DATA1. | ||
363 | For Isochronous endpoints: | ||
364 | Set Odd (micro)frame (SetOddFr) | ||
365 | Writing to this field sets the Even/Odd (micro)frame (EO_FrNum) | ||
366 | field to odd (micro)frame. */ | ||
367 | uint32_t setd0pid : 1; /**< For Interrupt/BULK enpoints: | ||
368 | Writing to this field sets the Endpoint Data Pid (DPID) field in | ||
369 | this register to DATA0. | ||
370 | For Isochronous endpoints: | ||
371 | Set Odd (micro)frame (SetEvenFr) | ||
372 | Writing to this field sets the Even/Odd (micro)frame (EO_FrNum) | ||
373 | field to even (micro)frame. */ | ||
374 | uint32_t snak : 1; /**< Set NAK (SNAK) | ||
375 | A write to this bit sets the NAK bit for the endpoint. | ||
376 | Using this bit, the application can control the transmission of | ||
377 | NAK handshakes on an endpoint. The core can also set this bit | ||
378 | for an endpoint after a SETUP packet is received on the | ||
379 | endpoint. */ | ||
380 | uint32_t cnak : 1; /**< Clear NAK (CNAK) | ||
381 | A write to this bit clears the NAK bit for the endpoint. */ | ||
382 | uint32_t txfnum : 4; /**< TxFIFO Number (TxFNum) | ||
383 | Non-periodic endpoints must set this bit to zero. Periodic | ||
384 | endpoints must map this to the corresponding Periodic TxFIFO | ||
385 | number. | ||
386 | * 4'h0: Non-Periodic TxFIFO | ||
387 | * Others: Specified Periodic TxFIFO number */ | ||
388 | uint32_t stall : 1; /**< STALL Handshake (Stall) | ||
389 | For non-control, non-isochronous endpoints: | ||
390 | The application sets this bit to stall all tokens from the USB host | ||
391 | to this endpoint. If a NAK bit, Global Non-Periodic IN NAK, or | ||
392 | Global OUT NAK is set along with this bit, the STALL bit takes | ||
393 | priority. Only the application can clear this bit, never the core. | ||
394 | For control endpoints: | ||
395 | The application can only set this bit, and the core clears it, when | ||
396 | a SETUP token i received for this endpoint. If a NAK bit, Global | ||
397 | Non-Periodic IN NAK, or Global OUT NAK is set along with this | ||
398 | bit, the STALL bit takes priority. Irrespective of this bit's setting, | ||
399 | the core always responds to SETUP data packets with an ACK handshake. */ | ||
400 | uint32_t reserved_20_20 : 1; | ||
401 | uint32_t eptype : 2; /**< Endpoint Type (EPType) | ||
402 | This is the transfer type supported by this logical endpoint. | ||
403 | * 2'b00: Control | ||
404 | * 2'b01: Isochronous | ||
405 | * 2'b10: Bulk | ||
406 | * 2'b11: Interrupt */ | ||
407 | uint32_t naksts : 1; /**< NAK Status (NAKSts) | ||
408 | Indicates the following: | ||
409 | * 1'b0: The core is transmitting non-NAK handshakes based | ||
410 | on the FIFO status | ||
411 | * 1'b1: The core is transmitting NAK handshakes on this | ||
412 | endpoint. | ||
413 | When either the application or the core sets this bit: | ||
414 | * For non-isochronous IN endpoints: The core stops | ||
415 | transmitting any data on an IN endpoint, even if data is | ||
416 | available in the TxFIFO. | ||
417 | * For isochronous IN endpoints: The core sends out a zero- | ||
418 | length data packet, even if data is available in the TxFIFO. | ||
419 | Irrespective of this bit's setting, the core always responds to | ||
420 | SETUP data packets with an ACK handshake. */ | ||
421 | uint32_t dpid : 1; /**< For interrupt/bulk IN and OUT endpoints: | ||
422 | Endpoint Data PID (DPID) | ||
423 | Contains the PID of the packet to be received or transmitted on | ||
424 | this endpoint. The application should program the PID of the first | ||
425 | packet to be received or transmitted on this endpoint, after the | ||
426 | endpoint is activated. Applications use the SetD1PID and | ||
427 | SetD0PID fields of this register to program either DATA0 or | ||
428 | DATA1 PID. | ||
429 | * 1'b0: DATA0 | ||
430 | * 1'b1: DATA1 | ||
431 | For isochronous IN and OUT endpoints: | ||
432 | Even/Odd (Micro)Frame (EO_FrNum) | ||
433 | Indicates the (micro)frame number in which the core transmits/ | ||
434 | receives isochronous data for this endpoint. The application | ||
435 | should program the even/odd (micro) frame number in which it | ||
436 | intends to transmit/receive isochronous data for this endpoint | ||
437 | using the SetEvnFr and SetOddFr fields in this register. | ||
438 | * 1'b0: Even (micro)frame | ||
439 | * 1'b1: Odd (micro)frame */ | ||
440 | uint32_t usbactep : 1; /**< USB Active Endpoint (USBActEP) | ||
441 | Indicates whether this endpoint is active in the current | ||
442 | configuration and interface. The core clears this bit for all | ||
443 | endpoints (other than EP 0) after detecting a USB reset. After | ||
444 | receiving the SetConfiguration and SetInterface commands, the | ||
445 | application must program endpoint registers accordingly and set | ||
446 | this bit. */ | ||
447 | uint32_t nextep : 4; /**< Next Endpoint (NextEp) | ||
448 | Applies to non-periodic IN endpoints only. | ||
449 | Indicates the endpoint number to be fetched after the data for | ||
450 | the current endpoint is fetched. The core can access this field, | ||
451 | even when the Endpoint Enable (EPEna) bit is not set. This | ||
452 | field is not valid in Slave mode. */ | ||
453 | uint32_t mps : 11; /**< Maximum Packet Size (MPS) | ||
454 | Applies to IN and OUT endpoints. | ||
455 | The application must program this field with the maximum | ||
456 | packet size for the current logical endpoint. This value is in | ||
457 | bytes. */ | ||
458 | } s; | ||
459 | struct cvmx_usbcx_diepctlx_s cn30xx; | ||
460 | struct cvmx_usbcx_diepctlx_s cn31xx; | ||
461 | struct cvmx_usbcx_diepctlx_s cn50xx; | ||
462 | struct cvmx_usbcx_diepctlx_s cn52xx; | ||
463 | struct cvmx_usbcx_diepctlx_s cn52xxp1; | ||
464 | struct cvmx_usbcx_diepctlx_s cn56xx; | ||
465 | struct cvmx_usbcx_diepctlx_s cn56xxp1; | ||
466 | }; | ||
467 | typedef union cvmx_usbcx_diepctlx cvmx_usbcx_diepctlx_t; | ||
468 | |||
469 | /** | ||
470 | * cvmx_usbc#_diepint# | ||
471 | * | ||
472 | * Device Endpoint-n Interrupt Register (DIEPINTn) | ||
473 | * | ||
474 | * This register indicates the status of an endpoint with respect to | ||
475 | * USB- and AHB-related events. The application must read this register | ||
476 | * when the OUT Endpoints Interrupt bit or IN Endpoints Interrupt bit of | ||
477 | * the Core Interrupt register (GINTSTS.OEPInt or GINTSTS.IEPInt, | ||
478 | * respectively) is set. Before the application can read this register, | ||
479 | * it must first read the Device All Endpoints Interrupt (DAINT) register | ||
480 | * to get the exact endpoint number for the Device Endpoint-n Interrupt | ||
481 | * register. The application must clear the appropriate bit in this register | ||
482 | * to clear the corresponding bits in the DAINT and GINTSTS registers. | ||
483 | */ | ||
484 | union cvmx_usbcx_diepintx | ||
485 | { | ||
486 | uint32_t u32; | ||
487 | struct cvmx_usbcx_diepintx_s | ||
488 | { | ||
489 | uint32_t reserved_7_31 : 25; | ||
490 | uint32_t inepnakeff : 1; /**< IN Endpoint NAK Effective (INEPNakEff) | ||
491 | Applies to periodic IN endpoints only. | ||
492 | Indicates that the IN endpoint NAK bit set by the application has | ||
493 | taken effect in the core. This bit can be cleared when the | ||
494 | application clears the IN endpoint NAK by writing to | ||
495 | DIEPCTLn.CNAK. | ||
496 | This interrupt indicates that the core has sampled the NAK bit | ||
497 | set (either by the application or by the core). | ||
498 | This interrupt does not necessarily mean that a NAK handshake | ||
499 | is sent on the USB. A STALL bit takes priority over a NAK bit. */ | ||
500 | uint32_t intknepmis : 1; /**< IN Token Received with EP Mismatch (INTknEPMis) | ||
501 | Applies to non-periodic IN endpoints only. | ||
502 | Indicates that the data in the top of the non-periodic TxFIFO | ||
503 | belongs to an endpoint other than the one for which the IN | ||
504 | token was received. This interrupt is asserted on the endpoint | ||
505 | for which the IN token was received. */ | ||
506 | uint32_t intkntxfemp : 1; /**< IN Token Received When TxFIFO is Empty (INTknTXFEmp) | ||
507 | Applies only to non-periodic IN endpoints. | ||
508 | Indicates that an IN token was received when the associated | ||
509 | TxFIFO (periodic/non-periodic) was empty. This interrupt is | ||
510 | asserted on the endpoint for which the IN token was received. */ | ||
511 | uint32_t timeout : 1; /**< Timeout Condition (TimeOUT) | ||
512 | Applies to non-isochronous IN endpoints only. | ||
513 | Indicates that the core has detected a timeout condition on the | ||
514 | USB for the last IN token on this endpoint. */ | ||
515 | uint32_t ahberr : 1; /**< AHB Error (AHBErr) | ||
516 | This is generated only in Internal DMA mode when there is an | ||
517 | AHB error during an AHB read/write. The application can read | ||
518 | the corresponding endpoint DMA address register to get the | ||
519 | error address. */ | ||
520 | uint32_t epdisbld : 1; /**< Endpoint Disabled Interrupt (EPDisbld) | ||
521 | This bit indicates that the endpoint is disabled per the | ||
522 | application's request. */ | ||
523 | uint32_t xfercompl : 1; /**< Transfer Completed Interrupt (XferCompl) | ||
524 | Indicates that the programmed transfer is complete on the AHB | ||
525 | as well as on the USB, for this endpoint. */ | ||
526 | } s; | ||
527 | struct cvmx_usbcx_diepintx_s cn30xx; | ||
528 | struct cvmx_usbcx_diepintx_s cn31xx; | ||
529 | struct cvmx_usbcx_diepintx_s cn50xx; | ||
530 | struct cvmx_usbcx_diepintx_s cn52xx; | ||
531 | struct cvmx_usbcx_diepintx_s cn52xxp1; | ||
532 | struct cvmx_usbcx_diepintx_s cn56xx; | ||
533 | struct cvmx_usbcx_diepintx_s cn56xxp1; | ||
534 | }; | ||
535 | typedef union cvmx_usbcx_diepintx cvmx_usbcx_diepintx_t; | ||
536 | |||
537 | /** | ||
538 | * cvmx_usbc#_diepmsk | ||
539 | * | ||
540 | * Device IN Endpoint Common Interrupt Mask Register (DIEPMSK) | ||
541 | * | ||
542 | * This register works with each of the Device IN Endpoint Interrupt (DIEPINTn) registers | ||
543 | * for all endpoints to generate an interrupt per IN endpoint. The IN endpoint interrupt | ||
544 | * for a specific status in the DIEPINTn register can be masked by writing to the corresponding | ||
545 | * bit in this register. Status bits are masked by default. | ||
546 | * Mask interrupt: 1'b0 Unmask interrupt: 1'b1 | ||
547 | */ | ||
548 | union cvmx_usbcx_diepmsk | ||
549 | { | ||
550 | uint32_t u32; | ||
551 | struct cvmx_usbcx_diepmsk_s | ||
552 | { | ||
553 | uint32_t reserved_7_31 : 25; | ||
554 | uint32_t inepnakeffmsk : 1; /**< IN Endpoint NAK Effective Mask (INEPNakEffMsk) */ | ||
555 | uint32_t intknepmismsk : 1; /**< IN Token received with EP Mismatch Mask (INTknEPMisMsk) */ | ||
556 | uint32_t intkntxfempmsk : 1; /**< IN Token Received When TxFIFO Empty Mask | ||
557 | (INTknTXFEmpMsk) */ | ||
558 | uint32_t timeoutmsk : 1; /**< Timeout Condition Mask (TimeOUTMsk) | ||
559 | (Non-isochronous endpoints) */ | ||
560 | uint32_t ahberrmsk : 1; /**< AHB Error Mask (AHBErrMsk) */ | ||
561 | uint32_t epdisbldmsk : 1; /**< Endpoint Disabled Interrupt Mask (EPDisbldMsk) */ | ||
562 | uint32_t xfercomplmsk : 1; /**< Transfer Completed Interrupt Mask (XferComplMsk) */ | ||
563 | } s; | ||
564 | struct cvmx_usbcx_diepmsk_s cn30xx; | ||
565 | struct cvmx_usbcx_diepmsk_s cn31xx; | ||
566 | struct cvmx_usbcx_diepmsk_s cn50xx; | ||
567 | struct cvmx_usbcx_diepmsk_s cn52xx; | ||
568 | struct cvmx_usbcx_diepmsk_s cn52xxp1; | ||
569 | struct cvmx_usbcx_diepmsk_s cn56xx; | ||
570 | struct cvmx_usbcx_diepmsk_s cn56xxp1; | ||
571 | }; | ||
572 | typedef union cvmx_usbcx_diepmsk cvmx_usbcx_diepmsk_t; | ||
573 | |||
574 | /** | ||
575 | * cvmx_usbc#_dieptsiz# | ||
576 | * | ||
577 | * Device Endpoint-n Transfer Size Register (DIEPTSIZn) | ||
578 | * | ||
579 | * The application must modify this register before enabling the endpoint. | ||
580 | * Once the endpoint is enabled using Endpoint Enable bit of the Device Endpoint-n Control registers (DIEPCTLn.EPEna/DOEPCTLn.EPEna), | ||
581 | * the core modifies this register. The application can only read this register once the core has cleared the Endpoint Enable bit. | ||
582 | * This register is used only for endpoints other than Endpoint 0. | ||
583 | */ | ||
584 | union cvmx_usbcx_dieptsizx | ||
585 | { | ||
586 | uint32_t u32; | ||
587 | struct cvmx_usbcx_dieptsizx_s | ||
588 | { | ||
589 | uint32_t reserved_31_31 : 1; | ||
590 | uint32_t mc : 2; /**< Multi Count (MC) | ||
591 | Applies to IN endpoints only. | ||
592 | For periodic IN endpoints, this field indicates the number of | ||
593 | packets that must be transmitted per microframe on the USB. | ||
594 | The core uses this field to calculate the data PID for | ||
595 | isochronous IN endpoints. | ||
596 | * 2'b01: 1 packet | ||
597 | * 2'b10: 2 packets | ||
598 | * 2'b11: 3 packets | ||
599 | For non-periodic IN endpoints, this field is valid only in Internal | ||
600 | DMA mode. It specifies the number of packets the core should | ||
601 | fetch for an IN endpoint before it switches to the endpoint | ||
602 | pointed to by the Next Endpoint field of the Device Endpoint-n | ||
603 | Control register (DIEPCTLn.NextEp) */ | ||
604 | uint32_t pktcnt : 10; /**< Packet Count (PktCnt) | ||
605 | Indicates the total number of USB packets that constitute the | ||
606 | Transfer Size amount of data for this endpoint. | ||
607 | IN Endpoints: This field is decremented every time a packet | ||
608 | (maximum size or short packet) is read from the TxFIFO. */ | ||
609 | uint32_t xfersize : 19; /**< Transfer Size (XferSize) | ||
610 | This field contains the transfer size in bytes for the current | ||
611 | endpoint. | ||
612 | The core only interrupts the application after it has exhausted | ||
613 | the transfer size amount of data. The transfer size can be set to | ||
614 | the maximum packet size of the endpoint, to be interrupted at | ||
615 | the end of each packet. | ||
616 | IN Endpoints: The core decrements this field every time a | ||
617 | packet from the external memory is written to the TxFIFO. */ | ||
618 | } s; | ||
619 | struct cvmx_usbcx_dieptsizx_s cn30xx; | ||
620 | struct cvmx_usbcx_dieptsizx_s cn31xx; | ||
621 | struct cvmx_usbcx_dieptsizx_s cn50xx; | ||
622 | struct cvmx_usbcx_dieptsizx_s cn52xx; | ||
623 | struct cvmx_usbcx_dieptsizx_s cn52xxp1; | ||
624 | struct cvmx_usbcx_dieptsizx_s cn56xx; | ||
625 | struct cvmx_usbcx_dieptsizx_s cn56xxp1; | ||
626 | }; | ||
627 | typedef union cvmx_usbcx_dieptsizx cvmx_usbcx_dieptsizx_t; | ||
628 | |||
629 | /** | ||
630 | * cvmx_usbc#_doepctl# | ||
631 | * | ||
632 | * Device OUT Endpoint-n Control Register (DOEPCTLn) | ||
633 | * | ||
634 | * The application uses the register to control the behaviour of each logical endpoint other than endpoint 0. | ||
635 | */ | ||
636 | union cvmx_usbcx_doepctlx | ||
637 | { | ||
638 | uint32_t u32; | ||
639 | struct cvmx_usbcx_doepctlx_s | ||
640 | { | ||
641 | uint32_t epena : 1; /**< Endpoint Enable (EPEna) | ||
642 | Indicates that the application has allocated the memory tp start | ||
643 | receiving data from the USB. | ||
644 | The core clears this bit before setting any of the following | ||
645 | interrupts on this endpoint: | ||
646 | * SETUP Phase Done | ||
647 | * Endpoint Disabled | ||
648 | * Transfer Completed | ||
649 | For control OUT endpoints in DMA mode, this bit must be set | ||
650 | to be able to transfer SETUP data packets in memory. */ | ||
651 | uint32_t epdis : 1; /**< Endpoint Disable (EPDis) | ||
652 | The application sets this bit to stop transmitting data on an | ||
653 | endpoint, even before the transfer for that endpoint is complete. | ||
654 | The application must wait for the Endpoint Disabled interrupt | ||
655 | before treating the endpoint as disabled. The core clears this bit | ||
656 | before setting the Endpoint Disabled Interrupt. The application | ||
657 | should set this bit only if Endpoint Enable is already set for this | ||
658 | endpoint. */ | ||
659 | uint32_t setd1pid : 1; /**< For Interrupt/BULK enpoints: | ||
660 | Set DATA1 PID (SetD1PID) | ||
661 | Writing to this field sets the Endpoint Data Pid (DPID) field in | ||
662 | this register to DATA1. | ||
663 | For Isochronous endpoints: | ||
664 | Set Odd (micro)frame (SetOddFr) | ||
665 | Writing to this field sets the Even/Odd (micro)frame (EO_FrNum) | ||
666 | field to odd (micro)frame. */ | ||
667 | uint32_t setd0pid : 1; /**< For Interrupt/BULK enpoints: | ||
668 | Writing to this field sets the Endpoint Data Pid (DPID) field in | ||
669 | this register to DATA0. | ||
670 | For Isochronous endpoints: | ||
671 | Set Odd (micro)frame (SetEvenFr) | ||
672 | Writing to this field sets the Even/Odd (micro)frame (EO_FrNum) | ||
673 | field to even (micro)frame. */ | ||
674 | uint32_t snak : 1; /**< Set NAK (SNAK) | ||
675 | A write to this bit sets the NAK bit for the endpoint. | ||
676 | Using this bit, the application can control the transmission of | ||
677 | NAK handshakes on an endpoint. The core can also set this bit | ||
678 | for an endpoint after a SETUP packet is received on the | ||
679 | endpoint. */ | ||
680 | uint32_t cnak : 1; /**< Clear NAK (CNAK) | ||
681 | A write to this bit clears the NAK bit for the endpoint. */ | ||
682 | uint32_t reserved_22_25 : 4; | ||
683 | uint32_t stall : 1; /**< STALL Handshake (Stall) | ||
684 | For non-control, non-isochronous endpoints: | ||
685 | The application sets this bit to stall all tokens from the USB host | ||
686 | to this endpoint. If a NAK bit, Global Non-Periodic IN NAK, or | ||
687 | Global OUT NAK is set along with this bit, the STALL bit takes | ||
688 | priority. Only the application can clear this bit, never the core. | ||
689 | For control endpoints: | ||
690 | The application can only set this bit, and the core clears it, when | ||
691 | a SETUP token i received for this endpoint. If a NAK bit, Global | ||
692 | Non-Periodic IN NAK, or Global OUT NAK is set along with this | ||
693 | bit, the STALL bit takes priority. Irrespective of this bit's setting, | ||
694 | the core always responds to SETUP data packets with an ACK handshake. */ | ||
695 | uint32_t snp : 1; /**< Snoop Mode (Snp) | ||
696 | This bit configures the endpoint to Snoop mode. In Snoop mode, | ||
697 | the core does not check the correctness of OUT packets before | ||
698 | transferring them to application memory. */ | ||
699 | uint32_t eptype : 2; /**< Endpoint Type (EPType) | ||
700 | This is the transfer type supported by this logical endpoint. | ||
701 | * 2'b00: Control | ||
702 | * 2'b01: Isochronous | ||
703 | * 2'b10: Bulk | ||
704 | * 2'b11: Interrupt */ | ||
705 | uint32_t naksts : 1; /**< NAK Status (NAKSts) | ||
706 | Indicates the following: | ||
707 | * 1'b0: The core is transmitting non-NAK handshakes based | ||
708 | on the FIFO status | ||
709 | * 1'b1: The core is transmitting NAK handshakes on this | ||
710 | endpoint. | ||
711 | When either the application or the core sets this bit: | ||
712 | * The core stops receiving any data on an OUT endpoint, even | ||
713 | if there is space in the RxFIFO to accomodate the incoming | ||
714 | packet. */ | ||
715 | uint32_t dpid : 1; /**< For interrupt/bulk IN and OUT endpoints: | ||
716 | Endpoint Data PID (DPID) | ||
717 | Contains the PID of the packet to be received or transmitted on | ||
718 | this endpoint. The application should program the PID of the first | ||
719 | packet to be received or transmitted on this endpoint, after the | ||
720 | endpoint is activated. Applications use the SetD1PID and | ||
721 | SetD0PID fields of this register to program either DATA0 or | ||
722 | DATA1 PID. | ||
723 | * 1'b0: DATA0 | ||
724 | * 1'b1: DATA1 | ||
725 | For isochronous IN and OUT endpoints: | ||
726 | Even/Odd (Micro)Frame (EO_FrNum) | ||
727 | Indicates the (micro)frame number in which the core transmits/ | ||
728 | receives isochronous data for this endpoint. The application | ||
729 | should program the even/odd (micro) frame number in which it | ||
730 | intends to transmit/receive isochronous data for this endpoint | ||
731 | using the SetEvnFr and SetOddFr fields in this register. | ||
732 | * 1'b0: Even (micro)frame | ||
733 | * 1'b1: Odd (micro)frame */ | ||
734 | uint32_t usbactep : 1; /**< USB Active Endpoint (USBActEP) | ||
735 | Indicates whether this endpoint is active in the current | ||
736 | configuration and interface. The core clears this bit for all | ||
737 | endpoints (other than EP 0) after detecting a USB reset. After | ||
738 | receiving the SetConfiguration and SetInterface commands, the | ||
739 | application must program endpoint registers accordingly and set | ||
740 | this bit. */ | ||
741 | uint32_t reserved_11_14 : 4; | ||
742 | uint32_t mps : 11; /**< Maximum Packet Size (MPS) | ||
743 | Applies to IN and OUT endpoints. | ||
744 | The application must program this field with the maximum | ||
745 | packet size for the current logical endpoint. This value is in | ||
746 | bytes. */ | ||
747 | } s; | ||
748 | struct cvmx_usbcx_doepctlx_s cn30xx; | ||
749 | struct cvmx_usbcx_doepctlx_s cn31xx; | ||
750 | struct cvmx_usbcx_doepctlx_s cn50xx; | ||
751 | struct cvmx_usbcx_doepctlx_s cn52xx; | ||
752 | struct cvmx_usbcx_doepctlx_s cn52xxp1; | ||
753 | struct cvmx_usbcx_doepctlx_s cn56xx; | ||
754 | struct cvmx_usbcx_doepctlx_s cn56xxp1; | ||
755 | }; | ||
756 | typedef union cvmx_usbcx_doepctlx cvmx_usbcx_doepctlx_t; | ||
757 | |||
758 | /** | ||
759 | * cvmx_usbc#_doepint# | ||
760 | * | ||
761 | * Device Endpoint-n Interrupt Register (DOEPINTn) | ||
762 | * | ||
763 | * This register indicates the status of an endpoint with respect to USB- and AHB-related events. | ||
764 | * The application must read this register when the OUT Endpoints Interrupt bit or IN Endpoints | ||
765 | * Interrupt bit of the Core Interrupt register (GINTSTS.OEPInt or GINTSTS.IEPInt, respectively) | ||
766 | * is set. Before the application can read this register, it must first read the Device All | ||
767 | * Endpoints Interrupt (DAINT) register to get the exact endpoint number for the Device Endpoint-n | ||
768 | * Interrupt register. The application must clear the appropriate bit in this register to clear the | ||
769 | * corresponding bits in the DAINT and GINTSTS registers. | ||
770 | */ | ||
771 | union cvmx_usbcx_doepintx | ||
772 | { | ||
773 | uint32_t u32; | ||
774 | struct cvmx_usbcx_doepintx_s | ||
775 | { | ||
776 | uint32_t reserved_5_31 : 27; | ||
777 | uint32_t outtknepdis : 1; /**< OUT Token Received When Endpoint Disabled (OUTTknEPdis) | ||
778 | Applies only to control OUT endpoints. | ||
779 | Indicates that an OUT token was received when the endpoint | ||
780 | was not yet enabled. This interrupt is asserted on the endpoint | ||
781 | for which the OUT token was received. */ | ||
782 | uint32_t setup : 1; /**< SETUP Phase Done (SetUp) | ||
783 | Applies to control OUT endpoints only. | ||
784 | Indicates that the SETUP phase for the control endpoint is | ||
785 | complete and no more back-to-back SETUP packets were | ||
786 | received for the current control transfer. On this interrupt, the | ||
787 | application can decode the received SETUP data packet. */ | ||
788 | uint32_t ahberr : 1; /**< AHB Error (AHBErr) | ||
789 | This is generated only in Internal DMA mode when there is an | ||
790 | AHB error during an AHB read/write. The application can read | ||
791 | the corresponding endpoint DMA address register to get the | ||
792 | error address. */ | ||
793 | uint32_t epdisbld : 1; /**< Endpoint Disabled Interrupt (EPDisbld) | ||
794 | This bit indicates that the endpoint is disabled per the | ||
795 | application's request. */ | ||
796 | uint32_t xfercompl : 1; /**< Transfer Completed Interrupt (XferCompl) | ||
797 | Indicates that the programmed transfer is complete on the AHB | ||
798 | as well as on the USB, for this endpoint. */ | ||
799 | } s; | ||
800 | struct cvmx_usbcx_doepintx_s cn30xx; | ||
801 | struct cvmx_usbcx_doepintx_s cn31xx; | ||
802 | struct cvmx_usbcx_doepintx_s cn50xx; | ||
803 | struct cvmx_usbcx_doepintx_s cn52xx; | ||
804 | struct cvmx_usbcx_doepintx_s cn52xxp1; | ||
805 | struct cvmx_usbcx_doepintx_s cn56xx; | ||
806 | struct cvmx_usbcx_doepintx_s cn56xxp1; | ||
807 | }; | ||
808 | typedef union cvmx_usbcx_doepintx cvmx_usbcx_doepintx_t; | ||
809 | |||
810 | /** | ||
811 | * cvmx_usbc#_doepmsk | ||
812 | * | ||
813 | * Device OUT Endpoint Common Interrupt Mask Register (DOEPMSK) | ||
814 | * | ||
815 | * This register works with each of the Device OUT Endpoint Interrupt (DOEPINTn) registers | ||
816 | * for all endpoints to generate an interrupt per OUT endpoint. The OUT endpoint interrupt | ||
817 | * for a specific status in the DOEPINTn register can be masked by writing into the | ||
818 | * corresponding bit in this register. Status bits are masked by default. | ||
819 | * Mask interrupt: 1'b0 Unmask interrupt: 1'b1 | ||
820 | */ | ||
821 | union cvmx_usbcx_doepmsk | ||
822 | { | ||
823 | uint32_t u32; | ||
824 | struct cvmx_usbcx_doepmsk_s | ||
825 | { | ||
826 | uint32_t reserved_5_31 : 27; | ||
827 | uint32_t outtknepdismsk : 1; /**< OUT Token Received when Endpoint Disabled Mask | ||
828 | (OUTTknEPdisMsk) | ||
829 | Applies to control OUT endpoints only. */ | ||
830 | uint32_t setupmsk : 1; /**< SETUP Phase Done Mask (SetUPMsk) | ||
831 | Applies to control endpoints only. */ | ||
832 | uint32_t ahberrmsk : 1; /**< AHB Error (AHBErrMsk) */ | ||
833 | uint32_t epdisbldmsk : 1; /**< Endpoint Disabled Interrupt Mask (EPDisbldMsk) */ | ||
834 | uint32_t xfercomplmsk : 1; /**< Transfer Completed Interrupt Mask (XferComplMsk) */ | ||
835 | } s; | ||
836 | struct cvmx_usbcx_doepmsk_s cn30xx; | ||
837 | struct cvmx_usbcx_doepmsk_s cn31xx; | ||
838 | struct cvmx_usbcx_doepmsk_s cn50xx; | ||
839 | struct cvmx_usbcx_doepmsk_s cn52xx; | ||
840 | struct cvmx_usbcx_doepmsk_s cn52xxp1; | ||
841 | struct cvmx_usbcx_doepmsk_s cn56xx; | ||
842 | struct cvmx_usbcx_doepmsk_s cn56xxp1; | ||
843 | }; | ||
844 | typedef union cvmx_usbcx_doepmsk cvmx_usbcx_doepmsk_t; | ||
845 | |||
846 | /** | ||
847 | * cvmx_usbc#_doeptsiz# | ||
848 | * | ||
849 | * Device Endpoint-n Transfer Size Register (DOEPTSIZn) | ||
850 | * | ||
851 | * The application must modify this register before enabling the endpoint. | ||
852 | * Once the endpoint is enabled using Endpoint Enable bit of the Device Endpoint-n Control | ||
853 | * registers (DOEPCTLn.EPEna/DOEPCTLn.EPEna), the core modifies this register. The application | ||
854 | * can only read this register once the core has cleared the Endpoint Enable bit. | ||
855 | * This register is used only for endpoints other than Endpoint 0. | ||
856 | */ | ||
857 | union cvmx_usbcx_doeptsizx | ||
858 | { | ||
859 | uint32_t u32; | ||
860 | struct cvmx_usbcx_doeptsizx_s | ||
861 | { | ||
862 | uint32_t reserved_31_31 : 1; | ||
863 | uint32_t mc : 2; /**< Multi Count (MC) | ||
864 | Received Data PID (RxDPID) | ||
865 | Applies to isochronous OUT endpoints only. | ||
866 | This is the data PID received in the last packet for this endpoint. | ||
867 | 2'b00: DATA0 | ||
868 | 2'b01: DATA1 | ||
869 | 2'b10: DATA2 | ||
870 | 2'b11: MDATA | ||
871 | SETUP Packet Count (SUPCnt) | ||
872 | Applies to control OUT Endpoints only. | ||
873 | This field specifies the number of back-to-back SETUP data | ||
874 | packets the endpoint can receive. | ||
875 | 2'b01: 1 packet | ||
876 | 2'b10: 2 packets | ||
877 | 2'b11: 3 packets */ | ||
878 | uint32_t pktcnt : 10; /**< Packet Count (PktCnt) | ||
879 | Indicates the total number of USB packets that constitute the | ||
880 | Transfer Size amount of data for this endpoint. | ||
881 | OUT Endpoints: This field is decremented every time a | ||
882 | packet (maximum size or short packet) is written to the | ||
883 | RxFIFO. */ | ||
884 | uint32_t xfersize : 19; /**< Transfer Size (XferSize) | ||
885 | This field contains the transfer size in bytes for the current | ||
886 | endpoint. | ||
887 | The core only interrupts the application after it has exhausted | ||
888 | the transfer size amount of data. The transfer size can be set to | ||
889 | the maximum packet size of the endpoint, to be interrupted at | ||
890 | the end of each packet. | ||
891 | OUT Endpoints: The core decrements this field every time a | ||
892 | packet is read from the RxFIFO and written to the external | ||
893 | memory. */ | ||
894 | } s; | ||
895 | struct cvmx_usbcx_doeptsizx_s cn30xx; | ||
896 | struct cvmx_usbcx_doeptsizx_s cn31xx; | ||
897 | struct cvmx_usbcx_doeptsizx_s cn50xx; | ||
898 | struct cvmx_usbcx_doeptsizx_s cn52xx; | ||
899 | struct cvmx_usbcx_doeptsizx_s cn52xxp1; | ||
900 | struct cvmx_usbcx_doeptsizx_s cn56xx; | ||
901 | struct cvmx_usbcx_doeptsizx_s cn56xxp1; | ||
902 | }; | ||
903 | typedef union cvmx_usbcx_doeptsizx cvmx_usbcx_doeptsizx_t; | ||
904 | |||
905 | /** | ||
906 | * cvmx_usbc#_dptxfsiz# | ||
907 | * | ||
908 | * Device Periodic Transmit FIFO-n Size Register (DPTXFSIZ) | ||
909 | * | ||
910 | * This register holds the memory start address of each periodic TxFIFO to implemented | ||
911 | * in Device mode. Each periodic FIFO holds the data for one periodic IN endpoint. | ||
912 | * This register is repeated for each periodic FIFO instantiated. | ||
913 | */ | ||
914 | union cvmx_usbcx_dptxfsizx | ||
915 | { | ||
916 | uint32_t u32; | ||
917 | struct cvmx_usbcx_dptxfsizx_s | ||
918 | { | ||
919 | uint32_t dptxfsize : 16; /**< Device Periodic TxFIFO Size (DPTxFSize) | ||
920 | This value is in terms of 32-bit words. | ||
921 | * Minimum value is 4 | ||
922 | * Maximum value is 768 */ | ||
923 | uint32_t dptxfstaddr : 16; /**< Device Periodic TxFIFO RAM Start Address (DPTxFStAddr) | ||
924 | Holds the start address in the RAM for this periodic FIFO. */ | ||
925 | } s; | ||
926 | struct cvmx_usbcx_dptxfsizx_s cn30xx; | ||
927 | struct cvmx_usbcx_dptxfsizx_s cn31xx; | ||
928 | struct cvmx_usbcx_dptxfsizx_s cn50xx; | ||
929 | struct cvmx_usbcx_dptxfsizx_s cn52xx; | ||
930 | struct cvmx_usbcx_dptxfsizx_s cn52xxp1; | ||
931 | struct cvmx_usbcx_dptxfsizx_s cn56xx; | ||
932 | struct cvmx_usbcx_dptxfsizx_s cn56xxp1; | ||
933 | }; | ||
934 | typedef union cvmx_usbcx_dptxfsizx cvmx_usbcx_dptxfsizx_t; | ||
935 | |||
936 | /** | ||
937 | * cvmx_usbc#_dsts | ||
938 | * | ||
939 | * Device Status Register (DSTS) | ||
940 | * | ||
941 | * This register indicates the status of the core with respect to USB-related events. | ||
942 | * It must be read on interrupts from Device All Interrupts (DAINT) register. | ||
943 | */ | ||
944 | union cvmx_usbcx_dsts | ||
945 | { | ||
946 | uint32_t u32; | ||
947 | struct cvmx_usbcx_dsts_s | ||
948 | { | ||
949 | uint32_t reserved_22_31 : 10; | ||
950 | uint32_t soffn : 14; /**< Frame or Microframe Number of the Received SOF (SOFFN) | ||
951 | When the core is operating at high speed, this field contains a | ||
952 | microframe number. When the core is operating at full or low | ||
953 | speed, this field contains a frame number. */ | ||
954 | uint32_t reserved_4_7 : 4; | ||
955 | uint32_t errticerr : 1; /**< Erratic Error (ErrticErr) | ||
956 | The core sets this bit to report any erratic errors | ||
957 | (phy_rxvalid_i/phy_rxvldh_i or phy_rxactive_i is asserted for at | ||
958 | least 2 ms, due to PHY error) seen on the UTMI+. | ||
959 | Due to erratic errors, the O2P USB core goes into Suspended | ||
960 | state and an interrupt is generated to the application with Early | ||
961 | Suspend bit of the Core Interrupt register (GINTSTS.ErlySusp). | ||
962 | If the early suspend is asserted due to an erratic error, the | ||
963 | application can only perform a soft disconnect recover. */ | ||
964 | uint32_t enumspd : 2; /**< Enumerated Speed (EnumSpd) | ||
965 | Indicates the speed at which the O2P USB core has come up | ||
966 | after speed detection through a chirp sequence. | ||
967 | * 2'b00: High speed (PHY clock is running at 30 or 60 MHz) | ||
968 | * 2'b01: Full speed (PHY clock is running at 30 or 60 MHz) | ||
969 | * 2'b10: Low speed (PHY clock is running at 6 MHz) | ||
970 | * 2'b11: Full speed (PHY clock is running at 48 MHz) | ||
971 | Low speed is not supported for devices using a UTMI+ PHY. */ | ||
972 | uint32_t suspsts : 1; /**< Suspend Status (SuspSts) | ||
973 | In Device mode, this bit is set as long as a Suspend condition is | ||
974 | detected on the USB. The core enters the Suspended state | ||
975 | when there is no activity on the phy_line_state_i signal for an | ||
976 | extended period of time. The core comes out of the suspend: | ||
977 | * When there is any activity on the phy_line_state_i signal | ||
978 | * When the application writes to the Remote Wakeup Signaling | ||
979 | bit in the Device Control register (DCTL.RmtWkUpSig). */ | ||
980 | } s; | ||
981 | struct cvmx_usbcx_dsts_s cn30xx; | ||
982 | struct cvmx_usbcx_dsts_s cn31xx; | ||
983 | struct cvmx_usbcx_dsts_s cn50xx; | ||
984 | struct cvmx_usbcx_dsts_s cn52xx; | ||
985 | struct cvmx_usbcx_dsts_s cn52xxp1; | ||
986 | struct cvmx_usbcx_dsts_s cn56xx; | ||
987 | struct cvmx_usbcx_dsts_s cn56xxp1; | ||
988 | }; | ||
989 | typedef union cvmx_usbcx_dsts cvmx_usbcx_dsts_t; | ||
990 | |||
991 | /** | ||
992 | * cvmx_usbc#_dtknqr1 | ||
993 | * | ||
994 | * Device IN Token Sequence Learning Queue Read Register 1 (DTKNQR1) | ||
995 | * | ||
996 | * The depth of the IN Token Sequence Learning Queue is specified for Device Mode IN Token | ||
997 | * Sequence Learning Queue Depth. The queue is 4 bits wide to store the endpoint number. | ||
998 | * A read from this register returns the first 5 endpoint entries of the IN Token Sequence | ||
999 | * Learning Queue. When the queue is full, the new token is pushed into the queue and oldest | ||
1000 | * token is discarded. | ||
1001 | */ | ||
1002 | union cvmx_usbcx_dtknqr1 | ||
1003 | { | ||
1004 | uint32_t u32; | ||
1005 | struct cvmx_usbcx_dtknqr1_s | ||
1006 | { | ||
1007 | uint32_t eptkn : 24; /**< Endpoint Token (EPTkn) | ||
1008 | Four bits per token represent the endpoint number of the token: | ||
1009 | * Bits [31:28]: Endpoint number of Token 5 | ||
1010 | * Bits [27:24]: Endpoint number of Token 4 | ||
1011 | - ....... | ||
1012 | * Bits [15:12]: Endpoint number of Token 1 | ||
1013 | * Bits [11:8]: Endpoint number of Token 0 */ | ||
1014 | uint32_t wrapbit : 1; /**< Wrap Bit (WrapBit) | ||
1015 | This bit is set when the write pointer wraps. It is cleared when | ||
1016 | the learning queue is cleared. */ | ||
1017 | uint32_t reserved_5_6 : 2; | ||
1018 | uint32_t intknwptr : 5; /**< IN Token Queue Write Pointer (INTknWPtr) */ | ||
1019 | } s; | ||
1020 | struct cvmx_usbcx_dtknqr1_s cn30xx; | ||
1021 | struct cvmx_usbcx_dtknqr1_s cn31xx; | ||
1022 | struct cvmx_usbcx_dtknqr1_s cn50xx; | ||
1023 | struct cvmx_usbcx_dtknqr1_s cn52xx; | ||
1024 | struct cvmx_usbcx_dtknqr1_s cn52xxp1; | ||
1025 | struct cvmx_usbcx_dtknqr1_s cn56xx; | ||
1026 | struct cvmx_usbcx_dtknqr1_s cn56xxp1; | ||
1027 | }; | ||
1028 | typedef union cvmx_usbcx_dtknqr1 cvmx_usbcx_dtknqr1_t; | ||
1029 | |||
1030 | /** | ||
1031 | * cvmx_usbc#_dtknqr2 | ||
1032 | * | ||
1033 | * Device IN Token Sequence Learning Queue Read Register 2 (DTKNQR2) | ||
1034 | * | ||
1035 | * A read from this register returns the next 8 endpoint entries of the learning queue. | ||
1036 | */ | ||
1037 | union cvmx_usbcx_dtknqr2 | ||
1038 | { | ||
1039 | uint32_t u32; | ||
1040 | struct cvmx_usbcx_dtknqr2_s | ||
1041 | { | ||
1042 | uint32_t eptkn : 32; /**< Endpoint Token (EPTkn) | ||
1043 | Four bits per token represent the endpoint number of the token: | ||
1044 | * Bits [31:28]: Endpoint number of Token 13 | ||
1045 | * Bits [27:24]: Endpoint number of Token 12 | ||
1046 | - ....... | ||
1047 | * Bits [7:4]: Endpoint number of Token 7 | ||
1048 | * Bits [3:0]: Endpoint number of Token 6 */ | ||
1049 | } s; | ||
1050 | struct cvmx_usbcx_dtknqr2_s cn30xx; | ||
1051 | struct cvmx_usbcx_dtknqr2_s cn31xx; | ||
1052 | struct cvmx_usbcx_dtknqr2_s cn50xx; | ||
1053 | struct cvmx_usbcx_dtknqr2_s cn52xx; | ||
1054 | struct cvmx_usbcx_dtknqr2_s cn52xxp1; | ||
1055 | struct cvmx_usbcx_dtknqr2_s cn56xx; | ||
1056 | struct cvmx_usbcx_dtknqr2_s cn56xxp1; | ||
1057 | }; | ||
1058 | typedef union cvmx_usbcx_dtknqr2 cvmx_usbcx_dtknqr2_t; | ||
1059 | |||
1060 | /** | ||
1061 | * cvmx_usbc#_dtknqr3 | ||
1062 | * | ||
1063 | * Device IN Token Sequence Learning Queue Read Register 3 (DTKNQR3) | ||
1064 | * | ||
1065 | * A read from this register returns the next 8 endpoint entries of the learning queue. | ||
1066 | */ | ||
1067 | union cvmx_usbcx_dtknqr3 | ||
1068 | { | ||
1069 | uint32_t u32; | ||
1070 | struct cvmx_usbcx_dtknqr3_s | ||
1071 | { | ||
1072 | uint32_t eptkn : 32; /**< Endpoint Token (EPTkn) | ||
1073 | Four bits per token represent the endpoint number of the token: | ||
1074 | * Bits [31:28]: Endpoint number of Token 21 | ||
1075 | * Bits [27:24]: Endpoint number of Token 20 | ||
1076 | - ....... | ||
1077 | * Bits [7:4]: Endpoint number of Token 15 | ||
1078 | * Bits [3:0]: Endpoint number of Token 14 */ | ||
1079 | } s; | ||
1080 | struct cvmx_usbcx_dtknqr3_s cn30xx; | ||
1081 | struct cvmx_usbcx_dtknqr3_s cn31xx; | ||
1082 | struct cvmx_usbcx_dtknqr3_s cn50xx; | ||
1083 | struct cvmx_usbcx_dtknqr3_s cn52xx; | ||
1084 | struct cvmx_usbcx_dtknqr3_s cn52xxp1; | ||
1085 | struct cvmx_usbcx_dtknqr3_s cn56xx; | ||
1086 | struct cvmx_usbcx_dtknqr3_s cn56xxp1; | ||
1087 | }; | ||
1088 | typedef union cvmx_usbcx_dtknqr3 cvmx_usbcx_dtknqr3_t; | ||
1089 | |||
1090 | /** | ||
1091 | * cvmx_usbc#_dtknqr4 | ||
1092 | * | ||
1093 | * Device IN Token Sequence Learning Queue Read Register 4 (DTKNQR4) | ||
1094 | * | ||
1095 | * A read from this register returns the last 8 endpoint entries of the learning queue. | ||
1096 | */ | ||
1097 | union cvmx_usbcx_dtknqr4 | ||
1098 | { | ||
1099 | uint32_t u32; | ||
1100 | struct cvmx_usbcx_dtknqr4_s | ||
1101 | { | ||
1102 | uint32_t eptkn : 32; /**< Endpoint Token (EPTkn) | ||
1103 | Four bits per token represent the endpoint number of the token: | ||
1104 | * Bits [31:28]: Endpoint number of Token 29 | ||
1105 | * Bits [27:24]: Endpoint number of Token 28 | ||
1106 | - ....... | ||
1107 | * Bits [7:4]: Endpoint number of Token 23 | ||
1108 | * Bits [3:0]: Endpoint number of Token 22 */ | ||
1109 | } s; | ||
1110 | struct cvmx_usbcx_dtknqr4_s cn30xx; | ||
1111 | struct cvmx_usbcx_dtknqr4_s cn31xx; | ||
1112 | struct cvmx_usbcx_dtknqr4_s cn50xx; | ||
1113 | struct cvmx_usbcx_dtknqr4_s cn52xx; | ||
1114 | struct cvmx_usbcx_dtknqr4_s cn52xxp1; | ||
1115 | struct cvmx_usbcx_dtknqr4_s cn56xx; | ||
1116 | struct cvmx_usbcx_dtknqr4_s cn56xxp1; | ||
1117 | }; | ||
1118 | typedef union cvmx_usbcx_dtknqr4 cvmx_usbcx_dtknqr4_t; | ||
1119 | |||
1120 | /** | ||
1121 | * cvmx_usbc#_gahbcfg | ||
1122 | * | ||
1123 | * Core AHB Configuration Register (GAHBCFG) | ||
1124 | * | ||
1125 | * This register can be used to configure the core after power-on or a change in mode of operation. | ||
1126 | * This register mainly contains AHB system-related configuration parameters. The AHB is the processor | ||
1127 | * interface to the O2P USB core. In general, software need not know about this interface except to | ||
1128 | * program the values as specified. | ||
1129 | * | ||
1130 | * The application must program this register as part of the O2P USB core initialization. | ||
1131 | * Do not change this register after the initial programming. | ||
1132 | */ | ||
1133 | union cvmx_usbcx_gahbcfg | ||
1134 | { | ||
1135 | uint32_t u32; | ||
1136 | struct cvmx_usbcx_gahbcfg_s | ||
1137 | { | ||
1138 | uint32_t reserved_9_31 : 23; | ||
1139 | uint32_t ptxfemplvl : 1; /**< Periodic TxFIFO Empty Level (PTxFEmpLvl) | ||
1140 | Software should set this bit to 0x1. | ||
1141 | Indicates when the Periodic TxFIFO Empty Interrupt bit in the | ||
1142 | Core Interrupt register (GINTSTS.PTxFEmp) is triggered. This | ||
1143 | bit is used only in Slave mode. | ||
1144 | * 1'b0: GINTSTS.PTxFEmp interrupt indicates that the Periodic | ||
1145 | TxFIFO is half empty | ||
1146 | * 1'b1: GINTSTS.PTxFEmp interrupt indicates that the Periodic | ||
1147 | TxFIFO is completely empty */ | ||
1148 | uint32_t nptxfemplvl : 1; /**< Non-Periodic TxFIFO Empty Level (NPTxFEmpLvl) | ||
1149 | Software should set this bit to 0x1. | ||
1150 | Indicates when the Non-Periodic TxFIFO Empty Interrupt bit in | ||
1151 | the Core Interrupt register (GINTSTS.NPTxFEmp) is triggered. | ||
1152 | This bit is used only in Slave mode. | ||
1153 | * 1'b0: GINTSTS.NPTxFEmp interrupt indicates that the Non- | ||
1154 | Periodic TxFIFO is half empty | ||
1155 | * 1'b1: GINTSTS.NPTxFEmp interrupt indicates that the Non- | ||
1156 | Periodic TxFIFO is completely empty */ | ||
1157 | uint32_t reserved_6_6 : 1; | ||
1158 | uint32_t dmaen : 1; /**< DMA Enable (DMAEn) | ||
1159 | * 1'b0: Core operates in Slave mode | ||
1160 | * 1'b1: Core operates in a DMA mode */ | ||
1161 | uint32_t hbstlen : 4; /**< Burst Length/Type (HBstLen) | ||
1162 | This field has not effect and should be left as 0x0. */ | ||
1163 | uint32_t glblintrmsk : 1; /**< Global Interrupt Mask (GlblIntrMsk) | ||
1164 | Software should set this field to 0x1. | ||
1165 | The application uses this bit to mask or unmask the interrupt | ||
1166 | line assertion to itself. Irrespective of this bit's setting, the | ||
1167 | interrupt status registers are updated by the core. | ||
1168 | * 1'b0: Mask the interrupt assertion to the application. | ||
1169 | * 1'b1: Unmask the interrupt assertion to the application. */ | ||
1170 | } s; | ||
1171 | struct cvmx_usbcx_gahbcfg_s cn30xx; | ||
1172 | struct cvmx_usbcx_gahbcfg_s cn31xx; | ||
1173 | struct cvmx_usbcx_gahbcfg_s cn50xx; | ||
1174 | struct cvmx_usbcx_gahbcfg_s cn52xx; | ||
1175 | struct cvmx_usbcx_gahbcfg_s cn52xxp1; | ||
1176 | struct cvmx_usbcx_gahbcfg_s cn56xx; | ||
1177 | struct cvmx_usbcx_gahbcfg_s cn56xxp1; | ||
1178 | }; | ||
1179 | typedef union cvmx_usbcx_gahbcfg cvmx_usbcx_gahbcfg_t; | ||
1180 | |||
1181 | /** | ||
1182 | * cvmx_usbc#_ghwcfg1 | ||
1183 | * | ||
1184 | * User HW Config1 Register (GHWCFG1) | ||
1185 | * | ||
1186 | * This register contains the logical endpoint direction(s) of the O2P USB core. | ||
1187 | */ | ||
1188 | union cvmx_usbcx_ghwcfg1 | ||
1189 | { | ||
1190 | uint32_t u32; | ||
1191 | struct cvmx_usbcx_ghwcfg1_s | ||
1192 | { | ||
1193 | uint32_t epdir : 32; /**< Endpoint Direction (epdir) | ||
1194 | Two bits per endpoint represent the direction. | ||
1195 | * 2'b00: BIDIR (IN and OUT) endpoint | ||
1196 | * 2'b01: IN endpoint | ||
1197 | * 2'b10: OUT endpoint | ||
1198 | * 2'b11: Reserved | ||
1199 | Bits [31:30]: Endpoint 15 direction | ||
1200 | Bits [29:28]: Endpoint 14 direction | ||
1201 | - ... | ||
1202 | Bits [3:2]: Endpoint 1 direction | ||
1203 | Bits[1:0]: Endpoint 0 direction (always BIDIR) */ | ||
1204 | } s; | ||
1205 | struct cvmx_usbcx_ghwcfg1_s cn30xx; | ||
1206 | struct cvmx_usbcx_ghwcfg1_s cn31xx; | ||
1207 | struct cvmx_usbcx_ghwcfg1_s cn50xx; | ||
1208 | struct cvmx_usbcx_ghwcfg1_s cn52xx; | ||
1209 | struct cvmx_usbcx_ghwcfg1_s cn52xxp1; | ||
1210 | struct cvmx_usbcx_ghwcfg1_s cn56xx; | ||
1211 | struct cvmx_usbcx_ghwcfg1_s cn56xxp1; | ||
1212 | }; | ||
1213 | typedef union cvmx_usbcx_ghwcfg1 cvmx_usbcx_ghwcfg1_t; | ||
1214 | |||
1215 | /** | ||
1216 | * cvmx_usbc#_ghwcfg2 | ||
1217 | * | ||
1218 | * User HW Config2 Register (GHWCFG2) | ||
1219 | * | ||
1220 | * This register contains configuration options of the O2P USB core. | ||
1221 | */ | ||
1222 | union cvmx_usbcx_ghwcfg2 | ||
1223 | { | ||
1224 | uint32_t u32; | ||
1225 | struct cvmx_usbcx_ghwcfg2_s | ||
1226 | { | ||
1227 | uint32_t reserved_31_31 : 1; | ||
1228 | uint32_t tknqdepth : 5; /**< Device Mode IN Token Sequence Learning Queue Depth | ||
1229 | (TknQDepth) | ||
1230 | Range: 0-30 */ | ||
1231 | uint32_t ptxqdepth : 2; /**< Host Mode Periodic Request Queue Depth (PTxQDepth) | ||
1232 | * 2'b00: 2 | ||
1233 | * 2'b01: 4 | ||
1234 | * 2'b10: 8 | ||
1235 | * Others: Reserved */ | ||
1236 | uint32_t nptxqdepth : 2; /**< Non-Periodic Request Queue Depth (NPTxQDepth) | ||
1237 | * 2'b00: 2 | ||
1238 | * 2'b01: 4 | ||
1239 | * 2'b10: 8 | ||
1240 | * Others: Reserved */ | ||
1241 | uint32_t reserved_20_21 : 2; | ||
1242 | uint32_t dynfifosizing : 1; /**< Dynamic FIFO Sizing Enabled (DynFifoSizing) | ||
1243 | * 1'b0: No | ||
1244 | * 1'b1: Yes */ | ||
1245 | uint32_t periosupport : 1; /**< Periodic OUT Channels Supported in Host Mode | ||
1246 | (PerioSupport) | ||
1247 | * 1'b0: No | ||
1248 | * 1'b1: Yes */ | ||
1249 | uint32_t numhstchnl : 4; /**< Number of Host Channels (NumHstChnl) | ||
1250 | Indicates the number of host channels supported by the core in | ||
1251 | Host mode. The range of this field is 0-15: 0 specifies 1 | ||
1252 | channel, 15 specifies 16 channels. */ | ||
1253 | uint32_t numdeveps : 4; /**< Number of Device Endpoints (NumDevEps) | ||
1254 | Indicates the number of device endpoints supported by the core | ||
1255 | in Device mode in addition to control endpoint 0. The range of | ||
1256 | this field is 1-15. */ | ||
1257 | uint32_t fsphytype : 2; /**< Full-Speed PHY Interface Type (FSPhyType) | ||
1258 | * 2'b00: Full-speed interface not supported | ||
1259 | * 2'b01: Dedicated full-speed interface | ||
1260 | * 2'b10: FS pins shared with UTMI+ pins | ||
1261 | * 2'b11: FS pins shared with ULPI pins */ | ||
1262 | uint32_t hsphytype : 2; /**< High-Speed PHY Interface Type (HSPhyType) | ||
1263 | * 2'b00: High-Speed interface not supported | ||
1264 | * 2'b01: UTMI+ | ||
1265 | * 2'b10: ULPI | ||
1266 | * 2'b11: UTMI+ and ULPI */ | ||
1267 | uint32_t singpnt : 1; /**< Point-to-Point (SingPnt) | ||
1268 | * 1'b0: Multi-point application | ||
1269 | * 1'b1: Single-point application */ | ||
1270 | uint32_t otgarch : 2; /**< Architecture (OtgArch) | ||
1271 | * 2'b00: Slave-Only | ||
1272 | * 2'b01: External DMA | ||
1273 | * 2'b10: Internal DMA | ||
1274 | * Others: Reserved */ | ||
1275 | uint32_t otgmode : 3; /**< Mode of Operation (OtgMode) | ||
1276 | * 3'b000: HNP- and SRP-Capable OTG (Host & Device) | ||
1277 | * 3'b001: SRP-Capable OTG (Host & Device) | ||
1278 | * 3'b010: Non-HNP and Non-SRP Capable OTG (Host & | ||
1279 | Device) | ||
1280 | * 3'b011: SRP-Capable Device | ||
1281 | * 3'b100: Non-OTG Device | ||
1282 | * 3'b101: SRP-Capable Host | ||
1283 | * 3'b110: Non-OTG Host | ||
1284 | * Others: Reserved */ | ||
1285 | } s; | ||
1286 | struct cvmx_usbcx_ghwcfg2_s cn30xx; | ||
1287 | struct cvmx_usbcx_ghwcfg2_s cn31xx; | ||
1288 | struct cvmx_usbcx_ghwcfg2_s cn50xx; | ||
1289 | struct cvmx_usbcx_ghwcfg2_s cn52xx; | ||
1290 | struct cvmx_usbcx_ghwcfg2_s cn52xxp1; | ||
1291 | struct cvmx_usbcx_ghwcfg2_s cn56xx; | ||
1292 | struct cvmx_usbcx_ghwcfg2_s cn56xxp1; | ||
1293 | }; | ||
1294 | typedef union cvmx_usbcx_ghwcfg2 cvmx_usbcx_ghwcfg2_t; | ||
1295 | |||
1296 | /** | ||
1297 | * cvmx_usbc#_ghwcfg3 | ||
1298 | * | ||
1299 | * User HW Config3 Register (GHWCFG3) | ||
1300 | * | ||
1301 | * This register contains the configuration options of the O2P USB core. | ||
1302 | */ | ||
1303 | union cvmx_usbcx_ghwcfg3 | ||
1304 | { | ||
1305 | uint32_t u32; | ||
1306 | struct cvmx_usbcx_ghwcfg3_s | ||
1307 | { | ||
1308 | uint32_t dfifodepth : 16; /**< DFIFO Depth (DfifoDepth) | ||
1309 | This value is in terms of 32-bit words. | ||
1310 | * Minimum value is 32 | ||
1311 | * Maximum value is 32768 */ | ||
1312 | uint32_t reserved_13_15 : 3; | ||
1313 | uint32_t ahbphysync : 1; /**< AHB and PHY Synchronous (AhbPhySync) | ||
1314 | Indicates whether AHB and PHY clocks are synchronous to | ||
1315 | each other. | ||
1316 | * 1'b0: No | ||
1317 | * 1'b1: Yes | ||
1318 | This bit is tied to 1. */ | ||
1319 | uint32_t rsttype : 1; /**< Reset Style for Clocked always Blocks in RTL (RstType) | ||
1320 | * 1'b0: Asynchronous reset is used in the core | ||
1321 | * 1'b1: Synchronous reset is used in the core */ | ||
1322 | uint32_t optfeature : 1; /**< Optional Features Removed (OptFeature) | ||
1323 | Indicates whether the User ID register, GPIO interface ports, | ||
1324 | and SOF toggle and counter ports were removed for gate count | ||
1325 | optimization. */ | ||
1326 | uint32_t vendor_control_interface_support : 1;/**< Vendor Control Interface Support | ||
1327 | * 1'b0: Vendor Control Interface is not available on the core. | ||
1328 | * 1'b1: Vendor Control Interface is available. */ | ||
1329 | uint32_t i2c_selection : 1; /**< I2C Selection | ||
1330 | * 1'b0: I2C Interface is not available on the core. | ||
1331 | * 1'b1: I2C Interface is available on the core. */ | ||
1332 | uint32_t otgen : 1; /**< OTG Function Enabled (OtgEn) | ||
1333 | The application uses this bit to indicate the O2P USB core's | ||
1334 | OTG capabilities. | ||
1335 | * 1'b0: Not OTG capable | ||
1336 | * 1'b1: OTG Capable */ | ||
1337 | uint32_t pktsizewidth : 3; /**< Width of Packet Size Counters (PktSizeWidth) | ||
1338 | * 3'b000: 4 bits | ||
1339 | * 3'b001: 5 bits | ||
1340 | * 3'b010: 6 bits | ||
1341 | * 3'b011: 7 bits | ||
1342 | * 3'b100: 8 bits | ||
1343 | * 3'b101: 9 bits | ||
1344 | * 3'b110: 10 bits | ||
1345 | * Others: Reserved */ | ||
1346 | uint32_t xfersizewidth : 4; /**< Width of Transfer Size Counters (XferSizeWidth) | ||
1347 | * 4'b0000: 11 bits | ||
1348 | * 4'b0001: 12 bits | ||
1349 | - ... | ||
1350 | * 4'b1000: 19 bits | ||
1351 | * Others: Reserved */ | ||
1352 | } s; | ||
1353 | struct cvmx_usbcx_ghwcfg3_s cn30xx; | ||
1354 | struct cvmx_usbcx_ghwcfg3_s cn31xx; | ||
1355 | struct cvmx_usbcx_ghwcfg3_s cn50xx; | ||
1356 | struct cvmx_usbcx_ghwcfg3_s cn52xx; | ||
1357 | struct cvmx_usbcx_ghwcfg3_s cn52xxp1; | ||
1358 | struct cvmx_usbcx_ghwcfg3_s cn56xx; | ||
1359 | struct cvmx_usbcx_ghwcfg3_s cn56xxp1; | ||
1360 | }; | ||
1361 | typedef union cvmx_usbcx_ghwcfg3 cvmx_usbcx_ghwcfg3_t; | ||
1362 | |||
1363 | /** | ||
1364 | * cvmx_usbc#_ghwcfg4 | ||
1365 | * | ||
1366 | * User HW Config4 Register (GHWCFG4) | ||
1367 | * | ||
1368 | * This register contains the configuration options of the O2P USB core. | ||
1369 | */ | ||
1370 | union cvmx_usbcx_ghwcfg4 | ||
1371 | { | ||
1372 | uint32_t u32; | ||
1373 | struct cvmx_usbcx_ghwcfg4_s | ||
1374 | { | ||
1375 | uint32_t reserved_30_31 : 2; | ||
1376 | uint32_t numdevmodinend : 4; /**< Enable dedicatd transmit FIFO for device IN endpoints. */ | ||
1377 | uint32_t endedtrfifo : 1; /**< Enable dedicatd transmit FIFO for device IN endpoints. */ | ||
1378 | uint32_t sessendfltr : 1; /**< "session_end" Filter Enabled (SessEndFltr) | ||
1379 | * 1'b0: No filter | ||
1380 | * 1'b1: Filter */ | ||
1381 | uint32_t bvalidfltr : 1; /**< "b_valid" Filter Enabled (BValidFltr) | ||
1382 | * 1'b0: No filter | ||
1383 | * 1'b1: Filter */ | ||
1384 | uint32_t avalidfltr : 1; /**< "a_valid" Filter Enabled (AValidFltr) | ||
1385 | * 1'b0: No filter | ||
1386 | * 1'b1: Filter */ | ||
1387 | uint32_t vbusvalidfltr : 1; /**< "vbus_valid" Filter Enabled (VBusValidFltr) | ||
1388 | * 1'b0: No filter | ||
1389 | * 1'b1: Filter */ | ||
1390 | uint32_t iddgfltr : 1; /**< "iddig" Filter Enable (IddgFltr) | ||
1391 | * 1'b0: No filter | ||
1392 | * 1'b1: Filter */ | ||
1393 | uint32_t numctleps : 4; /**< Number of Device Mode Control Endpoints in Addition to | ||
1394 | Endpoint 0 (NumCtlEps) | ||
1395 | Range: 1-15 */ | ||
1396 | uint32_t phydatawidth : 2; /**< UTMI+ PHY/ULPI-to-Internal UTMI+ Wrapper Data Width | ||
1397 | (PhyDataWidth) | ||
1398 | When a ULPI PHY is used, an internal wrapper converts ULPI | ||
1399 | to UTMI+. | ||
1400 | * 2'b00: 8 bits | ||
1401 | * 2'b01: 16 bits | ||
1402 | * 2'b10: 8/16 bits, software selectable | ||
1403 | * Others: Reserved */ | ||
1404 | uint32_t reserved_6_13 : 8; | ||
1405 | uint32_t ahbfreq : 1; /**< Minimum AHB Frequency Less Than 60 MHz (AhbFreq) | ||
1406 | * 1'b0: No | ||
1407 | * 1'b1: Yes */ | ||
1408 | uint32_t enablepwropt : 1; /**< Enable Power Optimization? (EnablePwrOpt) | ||
1409 | * 1'b0: No | ||
1410 | * 1'b1: Yes */ | ||
1411 | uint32_t numdevperioeps : 4; /**< Number of Device Mode Periodic IN Endpoints | ||
1412 | (NumDevPerioEps) | ||
1413 | Range: 0-15 */ | ||
1414 | } s; | ||
1415 | struct cvmx_usbcx_ghwcfg4_cn30xx | ||
1416 | { | ||
1417 | uint32_t reserved_25_31 : 7; | ||
1418 | uint32_t sessendfltr : 1; /**< "session_end" Filter Enabled (SessEndFltr) | ||
1419 | * 1'b0: No filter | ||
1420 | * 1'b1: Filter */ | ||
1421 | uint32_t bvalidfltr : 1; /**< "b_valid" Filter Enabled (BValidFltr) | ||
1422 | * 1'b0: No filter | ||
1423 | * 1'b1: Filter */ | ||
1424 | uint32_t avalidfltr : 1; /**< "a_valid" Filter Enabled (AValidFltr) | ||
1425 | * 1'b0: No filter | ||
1426 | * 1'b1: Filter */ | ||
1427 | uint32_t vbusvalidfltr : 1; /**< "vbus_valid" Filter Enabled (VBusValidFltr) | ||
1428 | * 1'b0: No filter | ||
1429 | * 1'b1: Filter */ | ||
1430 | uint32_t iddgfltr : 1; /**< "iddig" Filter Enable (IddgFltr) | ||
1431 | * 1'b0: No filter | ||
1432 | * 1'b1: Filter */ | ||
1433 | uint32_t numctleps : 4; /**< Number of Device Mode Control Endpoints in Addition to | ||
1434 | Endpoint 0 (NumCtlEps) | ||
1435 | Range: 1-15 */ | ||
1436 | uint32_t phydatawidth : 2; /**< UTMI+ PHY/ULPI-to-Internal UTMI+ Wrapper Data Width | ||
1437 | (PhyDataWidth) | ||
1438 | When a ULPI PHY is used, an internal wrapper converts ULPI | ||
1439 | to UTMI+. | ||
1440 | * 2'b00: 8 bits | ||
1441 | * 2'b01: 16 bits | ||
1442 | * 2'b10: 8/16 bits, software selectable | ||
1443 | * Others: Reserved */ | ||
1444 | uint32_t reserved_6_13 : 8; | ||
1445 | uint32_t ahbfreq : 1; /**< Minimum AHB Frequency Less Than 60 MHz (AhbFreq) | ||
1446 | * 1'b0: No | ||
1447 | * 1'b1: Yes */ | ||
1448 | uint32_t enablepwropt : 1; /**< Enable Power Optimization? (EnablePwrOpt) | ||
1449 | * 1'b0: No | ||
1450 | * 1'b1: Yes */ | ||
1451 | uint32_t numdevperioeps : 4; /**< Number of Device Mode Periodic IN Endpoints | ||
1452 | (NumDevPerioEps) | ||
1453 | Range: 0-15 */ | ||
1454 | } cn30xx; | ||
1455 | struct cvmx_usbcx_ghwcfg4_cn30xx cn31xx; | ||
1456 | struct cvmx_usbcx_ghwcfg4_s cn50xx; | ||
1457 | struct cvmx_usbcx_ghwcfg4_s cn52xx; | ||
1458 | struct cvmx_usbcx_ghwcfg4_s cn52xxp1; | ||
1459 | struct cvmx_usbcx_ghwcfg4_s cn56xx; | ||
1460 | struct cvmx_usbcx_ghwcfg4_s cn56xxp1; | ||
1461 | }; | ||
1462 | typedef union cvmx_usbcx_ghwcfg4 cvmx_usbcx_ghwcfg4_t; | ||
1463 | |||
1464 | /** | ||
1465 | * cvmx_usbc#_gintmsk | ||
1466 | * | ||
1467 | * Core Interrupt Mask Register (GINTMSK) | ||
1468 | * | ||
1469 | * This register works with the Core Interrupt register to interrupt the application. | ||
1470 | * When an interrupt bit is masked, the interrupt associated with that bit will not be generated. | ||
1471 | * However, the Core Interrupt (GINTSTS) register bit corresponding to that interrupt will still be set. | ||
1472 | * Mask interrupt: 1'b0, Unmask interrupt: 1'b1 | ||
1473 | */ | ||
1474 | union cvmx_usbcx_gintmsk | ||
1475 | { | ||
1476 | uint32_t u32; | ||
1477 | struct cvmx_usbcx_gintmsk_s | ||
1478 | { | ||
1479 | uint32_t wkupintmsk : 1; /**< Resume/Remote Wakeup Detected Interrupt Mask | ||
1480 | (WkUpIntMsk) */ | ||
1481 | uint32_t sessreqintmsk : 1; /**< Session Request/New Session Detected Interrupt Mask | ||
1482 | (SessReqIntMsk) */ | ||
1483 | uint32_t disconnintmsk : 1; /**< Disconnect Detected Interrupt Mask (DisconnIntMsk) */ | ||
1484 | uint32_t conidstschngmsk : 1; /**< Connector ID Status Change Mask (ConIDStsChngMsk) */ | ||
1485 | uint32_t reserved_27_27 : 1; | ||
1486 | uint32_t ptxfempmsk : 1; /**< Periodic TxFIFO Empty Mask (PTxFEmpMsk) */ | ||
1487 | uint32_t hchintmsk : 1; /**< Host Channels Interrupt Mask (HChIntMsk) */ | ||
1488 | uint32_t prtintmsk : 1; /**< Host Port Interrupt Mask (PrtIntMsk) */ | ||
1489 | uint32_t reserved_23_23 : 1; | ||
1490 | uint32_t fetsuspmsk : 1; /**< Data Fetch Suspended Mask (FetSuspMsk) */ | ||
1491 | uint32_t incomplpmsk : 1; /**< Incomplete Periodic Transfer Mask (incomplPMsk) | ||
1492 | Incomplete Isochronous OUT Transfer Mask | ||
1493 | (incompISOOUTMsk) */ | ||
1494 | uint32_t incompisoinmsk : 1; /**< Incomplete Isochronous IN Transfer Mask (incompISOINMsk) */ | ||
1495 | uint32_t oepintmsk : 1; /**< OUT Endpoints Interrupt Mask (OEPIntMsk) */ | ||
1496 | uint32_t inepintmsk : 1; /**< IN Endpoints Interrupt Mask (INEPIntMsk) */ | ||
1497 | uint32_t epmismsk : 1; /**< Endpoint Mismatch Interrupt Mask (EPMisMsk) */ | ||
1498 | uint32_t reserved_16_16 : 1; | ||
1499 | uint32_t eopfmsk : 1; /**< End of Periodic Frame Interrupt Mask (EOPFMsk) */ | ||
1500 | uint32_t isooutdropmsk : 1; /**< Isochronous OUT Packet Dropped Interrupt Mask | ||
1501 | (ISOOutDropMsk) */ | ||
1502 | uint32_t enumdonemsk : 1; /**< Enumeration Done Mask (EnumDoneMsk) */ | ||
1503 | uint32_t usbrstmsk : 1; /**< USB Reset Mask (USBRstMsk) */ | ||
1504 | uint32_t usbsuspmsk : 1; /**< USB Suspend Mask (USBSuspMsk) */ | ||
1505 | uint32_t erlysuspmsk : 1; /**< Early Suspend Mask (ErlySuspMsk) */ | ||
1506 | uint32_t i2cint : 1; /**< I2C Interrupt Mask (I2CINT) */ | ||
1507 | uint32_t ulpickintmsk : 1; /**< ULPI Carkit Interrupt Mask (ULPICKINTMsk) | ||
1508 | I2C Carkit Interrupt Mask (I2CCKINTMsk) */ | ||
1509 | uint32_t goutnakeffmsk : 1; /**< Global OUT NAK Effective Mask (GOUTNakEffMsk) */ | ||
1510 | uint32_t ginnakeffmsk : 1; /**< Global Non-Periodic IN NAK Effective Mask (GINNakEffMsk) */ | ||
1511 | uint32_t nptxfempmsk : 1; /**< Non-Periodic TxFIFO Empty Mask (NPTxFEmpMsk) */ | ||
1512 | uint32_t rxflvlmsk : 1; /**< Receive FIFO Non-Empty Mask (RxFLvlMsk) */ | ||
1513 | uint32_t sofmsk : 1; /**< Start of (micro)Frame Mask (SofMsk) */ | ||
1514 | uint32_t otgintmsk : 1; /**< OTG Interrupt Mask (OTGIntMsk) */ | ||
1515 | uint32_t modemismsk : 1; /**< Mode Mismatch Interrupt Mask (ModeMisMsk) */ | ||
1516 | uint32_t reserved_0_0 : 1; | ||
1517 | } s; | ||
1518 | struct cvmx_usbcx_gintmsk_s cn30xx; | ||
1519 | struct cvmx_usbcx_gintmsk_s cn31xx; | ||
1520 | struct cvmx_usbcx_gintmsk_s cn50xx; | ||
1521 | struct cvmx_usbcx_gintmsk_s cn52xx; | ||
1522 | struct cvmx_usbcx_gintmsk_s cn52xxp1; | ||
1523 | struct cvmx_usbcx_gintmsk_s cn56xx; | ||
1524 | struct cvmx_usbcx_gintmsk_s cn56xxp1; | ||
1525 | }; | ||
1526 | typedef union cvmx_usbcx_gintmsk cvmx_usbcx_gintmsk_t; | ||
1527 | |||
1528 | /** | ||
1529 | * cvmx_usbc#_gintsts | ||
1530 | * | ||
1531 | * Core Interrupt Register (GINTSTS) | ||
1532 | * | ||
1533 | * This register interrupts the application for system-level events in the current mode of operation | ||
1534 | * (Device mode or Host mode). It is shown in Interrupt. Some of the bits in this register are valid only in Host mode, | ||
1535 | * while others are valid in Device mode only. This register also indicates the current mode of operation. | ||
1536 | * In order to clear the interrupt status bits of type R_SS_WC, the application must write 1'b1 into the bit. | ||
1537 | * The FIFO status interrupts are read only; once software reads from or writes to the FIFO while servicing these | ||
1538 | * interrupts, FIFO interrupt conditions are cleared automatically. | ||
1539 | */ | ||
1540 | union cvmx_usbcx_gintsts | ||
1541 | { | ||
1542 | uint32_t u32; | ||
1543 | struct cvmx_usbcx_gintsts_s | ||
1544 | { | ||
1545 | uint32_t wkupint : 1; /**< Resume/Remote Wakeup Detected Interrupt (WkUpInt) | ||
1546 | In Device mode, this interrupt is asserted when a resume is | ||
1547 | detected on the USB. In Host mode, this interrupt is asserted | ||
1548 | when a remote wakeup is detected on the USB. | ||
1549 | For more information on how to use this interrupt, see "Partial | ||
1550 | Power-Down and Clock Gating Programming Model" on | ||
1551 | page 353. */ | ||
1552 | uint32_t sessreqint : 1; /**< Session Request/New Session Detected Interrupt (SessReqInt) | ||
1553 | In Host mode, this interrupt is asserted when a session request | ||
1554 | is detected from the device. In Device mode, this interrupt is | ||
1555 | asserted when the utmiotg_bvalid signal goes high. | ||
1556 | For more information on how to use this interrupt, see "Partial | ||
1557 | Power-Down and Clock Gating Programming Model" on | ||
1558 | page 353. */ | ||
1559 | uint32_t disconnint : 1; /**< Disconnect Detected Interrupt (DisconnInt) | ||
1560 | Asserted when a device disconnect is detected. */ | ||
1561 | uint32_t conidstschng : 1; /**< Connector ID Status Change (ConIDStsChng) | ||
1562 | The core sets this bit when there is a change in connector ID | ||
1563 | status. */ | ||
1564 | uint32_t reserved_27_27 : 1; | ||
1565 | uint32_t ptxfemp : 1; /**< Periodic TxFIFO Empty (PTxFEmp) | ||
1566 | Asserted when the Periodic Transmit FIFO is either half or | ||
1567 | completely empty and there is space for at least one entry to be | ||
1568 | written in the Periodic Request Queue. The half or completely | ||
1569 | empty status is determined by the Periodic TxFIFO Empty Level | ||
1570 | bit in the Core AHB Configuration register | ||
1571 | (GAHBCFG.PTxFEmpLvl). */ | ||
1572 | uint32_t hchint : 1; /**< Host Channels Interrupt (HChInt) | ||
1573 | The core sets this bit to indicate that an interrupt is pending on | ||
1574 | one of the channels of the core (in Host mode). The application | ||
1575 | must read the Host All Channels Interrupt (HAINT) register to | ||
1576 | determine the exact number of the channel on which the | ||
1577 | interrupt occurred, and then read the corresponding Host | ||
1578 | Channel-n Interrupt (HCINTn) register to determine the exact | ||
1579 | cause of the interrupt. The application must clear the | ||
1580 | appropriate status bit in the HCINTn register to clear this bit. */ | ||
1581 | uint32_t prtint : 1; /**< Host Port Interrupt (PrtInt) | ||
1582 | The core sets this bit to indicate a change in port status of one | ||
1583 | of the O2P USB core ports in Host mode. The application must | ||
1584 | read the Host Port Control and Status (HPRT) register to | ||
1585 | determine the exact event that caused this interrupt. The | ||
1586 | application must clear the appropriate status bit in the Host Port | ||
1587 | Control and Status register to clear this bit. */ | ||
1588 | uint32_t reserved_23_23 : 1; | ||
1589 | uint32_t fetsusp : 1; /**< Data Fetch Suspended (FetSusp) | ||
1590 | This interrupt is valid only in DMA mode. This interrupt indicates | ||
1591 | that the core has stopped fetching data for IN endpoints due to | ||
1592 | the unavailability of TxFIFO space or Request Queue space. | ||
1593 | This interrupt is used by the application for an endpoint | ||
1594 | mismatch algorithm. */ | ||
1595 | uint32_t incomplp : 1; /**< Incomplete Periodic Transfer (incomplP) | ||
1596 | In Host mode, the core sets this interrupt bit when there are | ||
1597 | incomplete periodic transactions still pending which are | ||
1598 | scheduled for the current microframe. | ||
1599 | Incomplete Isochronous OUT Transfer (incompISOOUT) | ||
1600 | The Device mode, the core sets this interrupt to indicate that | ||
1601 | there is at least one isochronous OUT endpoint on which the | ||
1602 | transfer is not completed in the current microframe. This | ||
1603 | interrupt is asserted along with the End of Periodic Frame | ||
1604 | Interrupt (EOPF) bit in this register. */ | ||
1605 | uint32_t incompisoin : 1; /**< Incomplete Isochronous IN Transfer (incompISOIN) | ||
1606 | The core sets this interrupt to indicate that there is at least one | ||
1607 | isochronous IN endpoint on which the transfer is not completed | ||
1608 | in the current microframe. This interrupt is asserted along with | ||
1609 | the End of Periodic Frame Interrupt (EOPF) bit in this register. */ | ||
1610 | uint32_t oepint : 1; /**< OUT Endpoints Interrupt (OEPInt) | ||
1611 | The core sets this bit to indicate that an interrupt is pending on | ||
1612 | one of the OUT endpoints of the core (in Device mode). The | ||
1613 | application must read the Device All Endpoints Interrupt | ||
1614 | (DAINT) register to determine the exact number of the OUT | ||
1615 | endpoint on which the interrupt occurred, and then read the | ||
1616 | corresponding Device OUT Endpoint-n Interrupt (DOEPINTn) | ||
1617 | register to determine the exact cause of the interrupt. The | ||
1618 | application must clear the appropriate status bit in the | ||
1619 | corresponding DOEPINTn register to clear this bit. */ | ||
1620 | uint32_t iepint : 1; /**< IN Endpoints Interrupt (IEPInt) | ||
1621 | The core sets this bit to indicate that an interrupt is pending on | ||
1622 | one of the IN endpoints of the core (in Device mode). The | ||
1623 | application must read the Device All Endpoints Interrupt | ||
1624 | (DAINT) register to determine the exact number of the IN | ||
1625 | endpoint on which the interrupt occurred, and then read the | ||
1626 | corresponding Device IN Endpoint-n Interrupt (DIEPINTn) | ||
1627 | register to determine the exact cause of the interrupt. The | ||
1628 | application must clear the appropriate status bit in the | ||
1629 | corresponding DIEPINTn register to clear this bit. */ | ||
1630 | uint32_t epmis : 1; /**< Endpoint Mismatch Interrupt (EPMis) | ||
1631 | Indicates that an IN token has been received for a non-periodic | ||
1632 | endpoint, but the data for another endpoint is present in the top | ||
1633 | of the Non-Periodic Transmit FIFO and the IN endpoint | ||
1634 | mismatch count programmed by the application has expired. */ | ||
1635 | uint32_t reserved_16_16 : 1; | ||
1636 | uint32_t eopf : 1; /**< End of Periodic Frame Interrupt (EOPF) | ||
1637 | Indicates that the period specified in the Periodic Frame Interval | ||
1638 | field of the Device Configuration register (DCFG.PerFrInt) has | ||
1639 | been reached in the current microframe. */ | ||
1640 | uint32_t isooutdrop : 1; /**< Isochronous OUT Packet Dropped Interrupt (ISOOutDrop) | ||
1641 | The core sets this bit when it fails to write an isochronous OUT | ||
1642 | packet into the RxFIFO because the RxFIFO doesn't have | ||
1643 | enough space to accommodate a maximum packet size packet | ||
1644 | for the isochronous OUT endpoint. */ | ||
1645 | uint32_t enumdone : 1; /**< Enumeration Done (EnumDone) | ||
1646 | The core sets this bit to indicate that speed enumeration is | ||
1647 | complete. The application must read the Device Status (DSTS) | ||
1648 | register to obtain the enumerated speed. */ | ||
1649 | uint32_t usbrst : 1; /**< USB Reset (USBRst) | ||
1650 | The core sets this bit to indicate that a reset is detected on the | ||
1651 | USB. */ | ||
1652 | uint32_t usbsusp : 1; /**< USB Suspend (USBSusp) | ||
1653 | The core sets this bit to indicate that a suspend was detected | ||
1654 | on the USB. The core enters the Suspended state when there | ||
1655 | is no activity on the phy_line_state_i signal for an extended | ||
1656 | period of time. */ | ||
1657 | uint32_t erlysusp : 1; /**< Early Suspend (ErlySusp) | ||
1658 | The core sets this bit to indicate that an Idle state has been | ||
1659 | detected on the USB for 3 ms. */ | ||
1660 | uint32_t i2cint : 1; /**< I2C Interrupt (I2CINT) | ||
1661 | This bit is always 0x0. */ | ||
1662 | uint32_t ulpickint : 1; /**< ULPI Carkit Interrupt (ULPICKINT) | ||
1663 | This bit is always 0x0. */ | ||
1664 | uint32_t goutnakeff : 1; /**< Global OUT NAK Effective (GOUTNakEff) | ||
1665 | Indicates that the Set Global OUT NAK bit in the Device Control | ||
1666 | register (DCTL.SGOUTNak), set by the application, has taken | ||
1667 | effect in the core. This bit can be cleared by writing the Clear | ||
1668 | Global OUT NAK bit in the Device Control register | ||
1669 | (DCTL.CGOUTNak). */ | ||
1670 | uint32_t ginnakeff : 1; /**< Global IN Non-Periodic NAK Effective (GINNakEff) | ||
1671 | Indicates that the Set Global Non-Periodic IN NAK bit in the | ||
1672 | Device Control register (DCTL.SGNPInNak), set by the | ||
1673 | application, has taken effect in the core. That is, the core has | ||
1674 | sampled the Global IN NAK bit set by the application. This bit | ||
1675 | can be cleared by clearing the Clear Global Non-Periodic IN | ||
1676 | NAK bit in the Device Control register (DCTL.CGNPInNak). | ||
1677 | This interrupt does not necessarily mean that a NAK handshake | ||
1678 | is sent out on the USB. The STALL bit takes precedence over | ||
1679 | the NAK bit. */ | ||
1680 | uint32_t nptxfemp : 1; /**< Non-Periodic TxFIFO Empty (NPTxFEmp) | ||
1681 | This interrupt is asserted when the Non-Periodic TxFIFO is | ||
1682 | either half or completely empty, and there is space for at least | ||
1683 | one entry to be written to the Non-Periodic Transmit Request | ||
1684 | Queue. The half or completely empty status is determined by | ||
1685 | the Non-Periodic TxFIFO Empty Level bit in the Core AHB | ||
1686 | Configuration register (GAHBCFG.NPTxFEmpLvl). */ | ||
1687 | uint32_t rxflvl : 1; /**< RxFIFO Non-Empty (RxFLvl) | ||
1688 | Indicates that there is at least one packet pending to be read | ||
1689 | from the RxFIFO. */ | ||
1690 | uint32_t sof : 1; /**< Start of (micro)Frame (Sof) | ||
1691 | In Host mode, the core sets this bit to indicate that an SOF | ||
1692 | (FS), micro-SOF (HS), or Keep-Alive (LS) is transmitted on the | ||
1693 | USB. The application must write a 1 to this bit to clear the | ||
1694 | interrupt. | ||
1695 | In Device mode, in the core sets this bit to indicate that an SOF | ||
1696 | token has been received on the USB. The application can read | ||
1697 | the Device Status register to get the current (micro)frame | ||
1698 | number. This interrupt is seen only when the core is operating | ||
1699 | at either HS or FS. */ | ||
1700 | uint32_t otgint : 1; /**< OTG Interrupt (OTGInt) | ||
1701 | The core sets this bit to indicate an OTG protocol event. The | ||
1702 | application must read the OTG Interrupt Status (GOTGINT) | ||
1703 | register to determine the exact event that caused this interrupt. | ||
1704 | The application must clear the appropriate status bit in the | ||
1705 | GOTGINT register to clear this bit. */ | ||
1706 | uint32_t modemis : 1; /**< Mode Mismatch Interrupt (ModeMis) | ||
1707 | The core sets this bit when the application is trying to access: | ||
1708 | * A Host mode register, when the core is operating in Device | ||
1709 | mode | ||
1710 | * A Device mode register, when the core is operating in Host | ||
1711 | mode | ||
1712 | The register access is completed on the AHB with an OKAY | ||
1713 | response, but is ignored by the core internally and doesn't | ||
1714 | affect the operation of the core. */ | ||
1715 | uint32_t curmod : 1; /**< Current Mode of Operation (CurMod) | ||
1716 | Indicates the current mode of operation. | ||
1717 | * 1'b0: Device mode | ||
1718 | * 1'b1: Host mode */ | ||
1719 | } s; | ||
1720 | struct cvmx_usbcx_gintsts_s cn30xx; | ||
1721 | struct cvmx_usbcx_gintsts_s cn31xx; | ||
1722 | struct cvmx_usbcx_gintsts_s cn50xx; | ||
1723 | struct cvmx_usbcx_gintsts_s cn52xx; | ||
1724 | struct cvmx_usbcx_gintsts_s cn52xxp1; | ||
1725 | struct cvmx_usbcx_gintsts_s cn56xx; | ||
1726 | struct cvmx_usbcx_gintsts_s cn56xxp1; | ||
1727 | }; | ||
1728 | typedef union cvmx_usbcx_gintsts cvmx_usbcx_gintsts_t; | ||
1729 | |||
1730 | /** | ||
1731 | * cvmx_usbc#_gnptxfsiz | ||
1732 | * | ||
1733 | * Non-Periodic Transmit FIFO Size Register (GNPTXFSIZ) | ||
1734 | * | ||
1735 | * The application can program the RAM size and the memory start address for the Non-Periodic TxFIFO. | ||
1736 | */ | ||
1737 | union cvmx_usbcx_gnptxfsiz | ||
1738 | { | ||
1739 | uint32_t u32; | ||
1740 | struct cvmx_usbcx_gnptxfsiz_s | ||
1741 | { | ||
1742 | uint32_t nptxfdep : 16; /**< Non-Periodic TxFIFO Depth (NPTxFDep) | ||
1743 | This value is in terms of 32-bit words. | ||
1744 | Minimum value is 16 | ||
1745 | Maximum value is 32768 */ | ||
1746 | uint32_t nptxfstaddr : 16; /**< Non-Periodic Transmit RAM Start Address (NPTxFStAddr) | ||
1747 | This field contains the memory start address for Non-Periodic | ||
1748 | Transmit FIFO RAM. */ | ||
1749 | } s; | ||
1750 | struct cvmx_usbcx_gnptxfsiz_s cn30xx; | ||
1751 | struct cvmx_usbcx_gnptxfsiz_s cn31xx; | ||
1752 | struct cvmx_usbcx_gnptxfsiz_s cn50xx; | ||
1753 | struct cvmx_usbcx_gnptxfsiz_s cn52xx; | ||
1754 | struct cvmx_usbcx_gnptxfsiz_s cn52xxp1; | ||
1755 | struct cvmx_usbcx_gnptxfsiz_s cn56xx; | ||
1756 | struct cvmx_usbcx_gnptxfsiz_s cn56xxp1; | ||
1757 | }; | ||
1758 | typedef union cvmx_usbcx_gnptxfsiz cvmx_usbcx_gnptxfsiz_t; | ||
1759 | |||
1760 | /** | ||
1761 | * cvmx_usbc#_gnptxsts | ||
1762 | * | ||
1763 | * Non-Periodic Transmit FIFO/Queue Status Register (GNPTXSTS) | ||
1764 | * | ||
1765 | * This read-only register contains the free space information for the Non-Periodic TxFIFO and | ||
1766 | * the Non-Periodic Transmit Request Queue | ||
1767 | */ | ||
1768 | union cvmx_usbcx_gnptxsts | ||
1769 | { | ||
1770 | uint32_t u32; | ||
1771 | struct cvmx_usbcx_gnptxsts_s | ||
1772 | { | ||
1773 | uint32_t reserved_31_31 : 1; | ||
1774 | uint32_t nptxqtop : 7; /**< Top of the Non-Periodic Transmit Request Queue (NPTxQTop) | ||
1775 | Entry in the Non-Periodic Tx Request Queue that is currently | ||
1776 | being processed by the MAC. | ||
1777 | * Bits [30:27]: Channel/endpoint number | ||
1778 | * Bits [26:25]: | ||
1779 | - 2'b00: IN/OUT token | ||
1780 | - 2'b01: Zero-length transmit packet (device IN/host OUT) | ||
1781 | - 2'b10: PING/CSPLIT token | ||
1782 | - 2'b11: Channel halt command | ||
1783 | * Bit [24]: Terminate (last entry for selected channel/endpoint) */ | ||
1784 | uint32_t nptxqspcavail : 8; /**< Non-Periodic Transmit Request Queue Space Available | ||
1785 | (NPTxQSpcAvail) | ||
1786 | Indicates the amount of free space available in the Non- | ||
1787 | Periodic Transmit Request Queue. This queue holds both IN | ||
1788 | and OUT requests in Host mode. Device mode has only IN | ||
1789 | requests. | ||
1790 | * 8'h0: Non-Periodic Transmit Request Queue is full | ||
1791 | * 8'h1: 1 location available | ||
1792 | * 8'h2: 2 locations available | ||
1793 | * n: n locations available (0..8) | ||
1794 | * Others: Reserved */ | ||
1795 | uint32_t nptxfspcavail : 16; /**< Non-Periodic TxFIFO Space Avail (NPTxFSpcAvail) | ||
1796 | Indicates the amount of free space available in the Non- | ||
1797 | Periodic TxFIFO. | ||
1798 | Values are in terms of 32-bit words. | ||
1799 | * 16'h0: Non-Periodic TxFIFO is full | ||
1800 | * 16'h1: 1 word available | ||
1801 | * 16'h2: 2 words available | ||
1802 | * 16'hn: n words available (where 0..32768) | ||
1803 | * 16'h8000: 32768 words available | ||
1804 | * Others: Reserved */ | ||
1805 | } s; | ||
1806 | struct cvmx_usbcx_gnptxsts_s cn30xx; | ||
1807 | struct cvmx_usbcx_gnptxsts_s cn31xx; | ||
1808 | struct cvmx_usbcx_gnptxsts_s cn50xx; | ||
1809 | struct cvmx_usbcx_gnptxsts_s cn52xx; | ||
1810 | struct cvmx_usbcx_gnptxsts_s cn52xxp1; | ||
1811 | struct cvmx_usbcx_gnptxsts_s cn56xx; | ||
1812 | struct cvmx_usbcx_gnptxsts_s cn56xxp1; | ||
1813 | }; | ||
1814 | typedef union cvmx_usbcx_gnptxsts cvmx_usbcx_gnptxsts_t; | ||
1815 | |||
1816 | /** | ||
1817 | * cvmx_usbc#_gotgctl | ||
1818 | * | ||
1819 | * OTG Control and Status Register (GOTGCTL) | ||
1820 | * | ||
1821 | * The OTG Control and Status register controls the behavior and reflects the status of the OTG function of the core.: | ||
1822 | */ | ||
1823 | union cvmx_usbcx_gotgctl | ||
1824 | { | ||
1825 | uint32_t u32; | ||
1826 | struct cvmx_usbcx_gotgctl_s | ||
1827 | { | ||
1828 | uint32_t reserved_20_31 : 12; | ||
1829 | uint32_t bsesvld : 1; /**< B-Session Valid (BSesVld) | ||
1830 | Valid only when O2P USB core is configured as a USB device. | ||
1831 | Indicates the Device mode transceiver status. | ||
1832 | * 1'b0: B-session is not valid. | ||
1833 | * 1'b1: B-session is valid. */ | ||
1834 | uint32_t asesvld : 1; /**< A-Session Valid (ASesVld) | ||
1835 | Valid only when O2P USB core is configured as a USB host. | ||
1836 | Indicates the Host mode transceiver status. | ||
1837 | * 1'b0: A-session is not valid | ||
1838 | * 1'b1: A-session is valid */ | ||
1839 | uint32_t dbnctime : 1; /**< Long/Short Debounce Time (DbncTime) | ||
1840 | In the present version of the core this bit will only read as '0'. */ | ||
1841 | uint32_t conidsts : 1; /**< Connector ID Status (ConIDSts) | ||
1842 | Indicates the connector ID status on a connect event. | ||
1843 | * 1'b0: The O2P USB core is in A-device mode | ||
1844 | * 1'b1: The O2P USB core is in B-device mode */ | ||
1845 | uint32_t reserved_12_15 : 4; | ||
1846 | uint32_t devhnpen : 1; /**< Device HNP Enabled (DevHNPEn) | ||
1847 | Since O2P USB core is not HNP capable this bit is 0x0. */ | ||
1848 | uint32_t hstsethnpen : 1; /**< Host Set HNP Enable (HstSetHNPEn) | ||
1849 | Since O2P USB core is not HNP capable this bit is 0x0. */ | ||
1850 | uint32_t hnpreq : 1; /**< HNP Request (HNPReq) | ||
1851 | Since O2P USB core is not HNP capable this bit is 0x0. */ | ||
1852 | uint32_t hstnegscs : 1; /**< Host Negotiation Success (HstNegScs) | ||
1853 | Since O2P USB core is not HNP capable this bit is 0x0. */ | ||
1854 | uint32_t reserved_2_7 : 6; | ||
1855 | uint32_t sesreq : 1; /**< Session Request (SesReq) | ||
1856 | Since O2P USB core is not SRP capable this bit is 0x0. */ | ||
1857 | uint32_t sesreqscs : 1; /**< Session Request Success (SesReqScs) | ||
1858 | Since O2P USB core is not SRP capable this bit is 0x0. */ | ||
1859 | } s; | ||
1860 | struct cvmx_usbcx_gotgctl_s cn30xx; | ||
1861 | struct cvmx_usbcx_gotgctl_s cn31xx; | ||
1862 | struct cvmx_usbcx_gotgctl_s cn50xx; | ||
1863 | struct cvmx_usbcx_gotgctl_s cn52xx; | ||
1864 | struct cvmx_usbcx_gotgctl_s cn52xxp1; | ||
1865 | struct cvmx_usbcx_gotgctl_s cn56xx; | ||
1866 | struct cvmx_usbcx_gotgctl_s cn56xxp1; | ||
1867 | }; | ||
1868 | typedef union cvmx_usbcx_gotgctl cvmx_usbcx_gotgctl_t; | ||
1869 | |||
1870 | /** | ||
1871 | * cvmx_usbc#_gotgint | ||
1872 | * | ||
1873 | * OTG Interrupt Register (GOTGINT) | ||
1874 | * | ||
1875 | * The application reads this register whenever there is an OTG interrupt and clears the bits in this register | ||
1876 | * to clear the OTG interrupt. It is shown in Interrupt .: | ||
1877 | */ | ||
1878 | union cvmx_usbcx_gotgint | ||
1879 | { | ||
1880 | uint32_t u32; | ||
1881 | struct cvmx_usbcx_gotgint_s | ||
1882 | { | ||
1883 | uint32_t reserved_20_31 : 12; | ||
1884 | uint32_t dbncedone : 1; /**< Debounce Done (DbnceDone) | ||
1885 | In the present version of the code this bit is tied to '0'. */ | ||
1886 | uint32_t adevtoutchg : 1; /**< A-Device Timeout Change (ADevTOUTChg) | ||
1887 | Since O2P USB core is not HNP or SRP capable this bit is always 0x0. */ | ||
1888 | uint32_t hstnegdet : 1; /**< Host Negotiation Detected (HstNegDet) | ||
1889 | Since O2P USB core is not HNP or SRP capable this bit is always 0x0. */ | ||
1890 | uint32_t reserved_10_16 : 7; | ||
1891 | uint32_t hstnegsucstschng : 1; /**< Host Negotiation Success Status Change (HstNegSucStsChng) | ||
1892 | Since O2P USB core is not HNP or SRP capable this bit is always 0x0. */ | ||
1893 | uint32_t sesreqsucstschng : 1; /**< Session Request Success Status Change | ||
1894 | Since O2P USB core is not HNP or SRP capable this bit is always 0x0. */ | ||
1895 | uint32_t reserved_3_7 : 5; | ||
1896 | uint32_t sesenddet : 1; /**< Session End Detected (SesEndDet) | ||
1897 | Since O2P USB core is not HNP or SRP capable this bit is always 0x0. */ | ||
1898 | uint32_t reserved_0_1 : 2; | ||
1899 | } s; | ||
1900 | struct cvmx_usbcx_gotgint_s cn30xx; | ||
1901 | struct cvmx_usbcx_gotgint_s cn31xx; | ||
1902 | struct cvmx_usbcx_gotgint_s cn50xx; | ||
1903 | struct cvmx_usbcx_gotgint_s cn52xx; | ||
1904 | struct cvmx_usbcx_gotgint_s cn52xxp1; | ||
1905 | struct cvmx_usbcx_gotgint_s cn56xx; | ||
1906 | struct cvmx_usbcx_gotgint_s cn56xxp1; | ||
1907 | }; | ||
1908 | typedef union cvmx_usbcx_gotgint cvmx_usbcx_gotgint_t; | ||
1909 | |||
1910 | /** | ||
1911 | * cvmx_usbc#_grstctl | ||
1912 | * | ||
1913 | * Core Reset Register (GRSTCTL) | ||
1914 | * | ||
1915 | * The application uses this register to reset various hardware features inside the core. | ||
1916 | */ | ||
1917 | union cvmx_usbcx_grstctl | ||
1918 | { | ||
1919 | uint32_t u32; | ||
1920 | struct cvmx_usbcx_grstctl_s | ||
1921 | { | ||
1922 | uint32_t ahbidle : 1; /**< AHB Master Idle (AHBIdle) | ||
1923 | Indicates that the AHB Master State Machine is in the IDLE | ||
1924 | condition. */ | ||
1925 | uint32_t dmareq : 1; /**< DMA Request Signal (DMAReq) | ||
1926 | Indicates that the DMA request is in progress. Used for debug. */ | ||
1927 | uint32_t reserved_11_29 : 19; | ||
1928 | uint32_t txfnum : 5; /**< TxFIFO Number (TxFNum) | ||
1929 | This is the FIFO number that must be flushed using the TxFIFO | ||
1930 | Flush bit. This field must not be changed until the core clears | ||
1931 | the TxFIFO Flush bit. | ||
1932 | * 5'h0: Non-Periodic TxFIFO flush | ||
1933 | * 5'h1: Periodic TxFIFO 1 flush in Device mode or Periodic | ||
1934 | TxFIFO flush in Host mode | ||
1935 | * 5'h2: Periodic TxFIFO 2 flush in Device mode | ||
1936 | - ... | ||
1937 | * 5'hF: Periodic TxFIFO 15 flush in Device mode | ||
1938 | * 5'h10: Flush all the Periodic and Non-Periodic TxFIFOs in the | ||
1939 | core */ | ||
1940 | uint32_t txfflsh : 1; /**< TxFIFO Flush (TxFFlsh) | ||
1941 | This bit selectively flushes a single or all transmit FIFOs, but | ||
1942 | cannot do so if the core is in the midst of a transaction. | ||
1943 | The application must only write this bit after checking that the | ||
1944 | core is neither writing to the TxFIFO nor reading from the | ||
1945 | TxFIFO. | ||
1946 | The application must wait until the core clears this bit before | ||
1947 | performing any operations. This bit takes 8 clocks (of phy_clk or | ||
1948 | hclk, whichever is slower) to clear. */ | ||
1949 | uint32_t rxfflsh : 1; /**< RxFIFO Flush (RxFFlsh) | ||
1950 | The application can flush the entire RxFIFO using this bit, but | ||
1951 | must first ensure that the core is not in the middle of a | ||
1952 | transaction. | ||
1953 | The application must only write to this bit after checking that the | ||
1954 | core is neither reading from the RxFIFO nor writing to the | ||
1955 | RxFIFO. | ||
1956 | The application must wait until the bit is cleared before | ||
1957 | performing any other operations. This bit will take 8 clocks | ||
1958 | (slowest of PHY or AHB clock) to clear. */ | ||
1959 | uint32_t intknqflsh : 1; /**< IN Token Sequence Learning Queue Flush (INTknQFlsh) | ||
1960 | The application writes this bit to flush the IN Token Sequence | ||
1961 | Learning Queue. */ | ||
1962 | uint32_t frmcntrrst : 1; /**< Host Frame Counter Reset (FrmCntrRst) | ||
1963 | The application writes this bit to reset the (micro)frame number | ||
1964 | counter inside the core. When the (micro)frame counter is reset, | ||
1965 | the subsequent SOF sent out by the core will have a | ||
1966 | (micro)frame number of 0. */ | ||
1967 | uint32_t hsftrst : 1; /**< HClk Soft Reset (HSftRst) | ||
1968 | The application uses this bit to flush the control logic in the AHB | ||
1969 | Clock domain. Only AHB Clock Domain pipelines are reset. | ||
1970 | * FIFOs are not flushed with this bit. | ||
1971 | * All state machines in the AHB clock domain are reset to the | ||
1972 | Idle state after terminating the transactions on the AHB, | ||
1973 | following the protocol. | ||
1974 | * CSR control bits used by the AHB clock domain state | ||
1975 | machines are cleared. | ||
1976 | * To clear this interrupt, status mask bits that control the | ||
1977 | interrupt status and are generated by the AHB clock domain | ||
1978 | state machine are cleared. | ||
1979 | * Because interrupt status bits are not cleared, the application | ||
1980 | can get the status of any core events that occurred after it set | ||
1981 | this bit. | ||
1982 | This is a self-clearing bit that the core clears after all necessary | ||
1983 | logic is reset in the core. This may take several clocks, | ||
1984 | depending on the core's current state. */ | ||
1985 | uint32_t csftrst : 1; /**< Core Soft Reset (CSftRst) | ||
1986 | Resets the hclk and phy_clock domains as follows: | ||
1987 | * Clears the interrupts and all the CSR registers except the | ||
1988 | following register bits: | ||
1989 | - PCGCCTL.RstPdwnModule | ||
1990 | - PCGCCTL.GateHclk | ||
1991 | - PCGCCTL.PwrClmp | ||
1992 | - PCGCCTL.StopPPhyLPwrClkSelclk | ||
1993 | - GUSBCFG.PhyLPwrClkSel | ||
1994 | - GUSBCFG.DDRSel | ||
1995 | - GUSBCFG.PHYSel | ||
1996 | - GUSBCFG.FSIntf | ||
1997 | - GUSBCFG.ULPI_UTMI_Sel | ||
1998 | - GUSBCFG.PHYIf | ||
1999 | - HCFG.FSLSPclkSel | ||
2000 | - DCFG.DevSpd | ||
2001 | * All module state machines (except the AHB Slave Unit) are | ||
2002 | reset to the IDLE state, and all the transmit FIFOs and the | ||
2003 | receive FIFO are flushed. | ||
2004 | * Any transactions on the AHB Master are terminated as soon | ||
2005 | as possible, after gracefully completing the last data phase of | ||
2006 | an AHB transfer. Any transactions on the USB are terminated | ||
2007 | immediately. | ||
2008 | The application can write to this bit any time it wants to reset | ||
2009 | the core. This is a self-clearing bit and the core clears this bit | ||
2010 | after all the necessary logic is reset in the core, which may take | ||
2011 | several clocks, depending on the current state of the core. | ||
2012 | Once this bit is cleared software should wait at least 3 PHY | ||
2013 | clocks before doing any access to the PHY domain | ||
2014 | (synchronization delay). Software should also should check that | ||
2015 | bit 31 of this register is 1 (AHB Master is IDLE) before starting | ||
2016 | any operation. | ||
2017 | Typically software reset is used during software development | ||
2018 | and also when you dynamically change the PHY selection bits | ||
2019 | in the USB configuration registers listed above. When you | ||
2020 | change the PHY, the corresponding clock for the PHY is | ||
2021 | selected and used in the PHY domain. Once a new clock is | ||
2022 | selected, the PHY domain has to be reset for proper operation. */ | ||
2023 | } s; | ||
2024 | struct cvmx_usbcx_grstctl_s cn30xx; | ||
2025 | struct cvmx_usbcx_grstctl_s cn31xx; | ||
2026 | struct cvmx_usbcx_grstctl_s cn50xx; | ||
2027 | struct cvmx_usbcx_grstctl_s cn52xx; | ||
2028 | struct cvmx_usbcx_grstctl_s cn52xxp1; | ||
2029 | struct cvmx_usbcx_grstctl_s cn56xx; | ||
2030 | struct cvmx_usbcx_grstctl_s cn56xxp1; | ||
2031 | }; | ||
2032 | typedef union cvmx_usbcx_grstctl cvmx_usbcx_grstctl_t; | ||
2033 | |||
2034 | /** | ||
2035 | * cvmx_usbc#_grxfsiz | ||
2036 | * | ||
2037 | * Receive FIFO Size Register (GRXFSIZ) | ||
2038 | * | ||
2039 | * The application can program the RAM size that must be allocated to the RxFIFO. | ||
2040 | */ | ||
2041 | union cvmx_usbcx_grxfsiz | ||
2042 | { | ||
2043 | uint32_t u32; | ||
2044 | struct cvmx_usbcx_grxfsiz_s | ||
2045 | { | ||
2046 | uint32_t reserved_16_31 : 16; | ||
2047 | uint32_t rxfdep : 16; /**< RxFIFO Depth (RxFDep) | ||
2048 | This value is in terms of 32-bit words. | ||
2049 | * Minimum value is 16 | ||
2050 | * Maximum value is 32768 */ | ||
2051 | } s; | ||
2052 | struct cvmx_usbcx_grxfsiz_s cn30xx; | ||
2053 | struct cvmx_usbcx_grxfsiz_s cn31xx; | ||
2054 | struct cvmx_usbcx_grxfsiz_s cn50xx; | ||
2055 | struct cvmx_usbcx_grxfsiz_s cn52xx; | ||
2056 | struct cvmx_usbcx_grxfsiz_s cn52xxp1; | ||
2057 | struct cvmx_usbcx_grxfsiz_s cn56xx; | ||
2058 | struct cvmx_usbcx_grxfsiz_s cn56xxp1; | ||
2059 | }; | ||
2060 | typedef union cvmx_usbcx_grxfsiz cvmx_usbcx_grxfsiz_t; | ||
2061 | |||
2062 | /** | ||
2063 | * cvmx_usbc#_grxstspd | ||
2064 | * | ||
2065 | * Receive Status Debug Read Register, Device Mode (GRXSTSPD) | ||
2066 | * | ||
2067 | * A read to the Receive Status Read and Pop register returns and additionally pops the top data entry out of the RxFIFO. | ||
2068 | * This Description is only valid when the core is in Device Mode. For Host Mode use USBC_GRXSTSPH instead. | ||
2069 | * NOTE: GRXSTSPH and GRXSTSPD are physically the same register and share the same offset in the O2P USB core. | ||
2070 | * The offset difference shown in this document is for software clarity and is actually ignored by the | ||
2071 | * hardware. | ||
2072 | */ | ||
2073 | union cvmx_usbcx_grxstspd | ||
2074 | { | ||
2075 | uint32_t u32; | ||
2076 | struct cvmx_usbcx_grxstspd_s | ||
2077 | { | ||
2078 | uint32_t reserved_25_31 : 7; | ||
2079 | uint32_t fn : 4; /**< Frame Number (FN) | ||
2080 | This is the least significant 4 bits of the (micro)frame number in | ||
2081 | which the packet is received on the USB. This field is supported | ||
2082 | only when the isochronous OUT endpoints are supported. */ | ||
2083 | uint32_t pktsts : 4; /**< Packet Status (PktSts) | ||
2084 | Indicates the status of the received packet | ||
2085 | * 4'b0001: Glogal OUT NAK (triggers an interrupt) | ||
2086 | * 4'b0010: OUT data packet received | ||
2087 | * 4'b0100: SETUP transaction completed (triggers an interrupt) | ||
2088 | * 4'b0110: SETUP data packet received | ||
2089 | * Others: Reserved */ | ||
2090 | uint32_t dpid : 2; /**< Data PID (DPID) | ||
2091 | * 2'b00: DATA0 | ||
2092 | * 2'b10: DATA1 | ||
2093 | * 2'b01: DATA2 | ||
2094 | * 2'b11: MDATA */ | ||
2095 | uint32_t bcnt : 11; /**< Byte Count (BCnt) | ||
2096 | Indicates the byte count of the received data packet */ | ||
2097 | uint32_t epnum : 4; /**< Endpoint Number (EPNum) | ||
2098 | Indicates the endpoint number to which the current received | ||
2099 | packet belongs. */ | ||
2100 | } s; | ||
2101 | struct cvmx_usbcx_grxstspd_s cn30xx; | ||
2102 | struct cvmx_usbcx_grxstspd_s cn31xx; | ||
2103 | struct cvmx_usbcx_grxstspd_s cn50xx; | ||
2104 | struct cvmx_usbcx_grxstspd_s cn52xx; | ||
2105 | struct cvmx_usbcx_grxstspd_s cn52xxp1; | ||
2106 | struct cvmx_usbcx_grxstspd_s cn56xx; | ||
2107 | struct cvmx_usbcx_grxstspd_s cn56xxp1; | ||
2108 | }; | ||
2109 | typedef union cvmx_usbcx_grxstspd cvmx_usbcx_grxstspd_t; | ||
2110 | |||
2111 | /** | ||
2112 | * cvmx_usbc#_grxstsph | ||
2113 | * | ||
2114 | * Receive Status Read and Pop Register, Host Mode (GRXSTSPH) | ||
2115 | * | ||
2116 | * A read to the Receive Status Read and Pop register returns and additionally pops the top data entry out of the RxFIFO. | ||
2117 | * This Description is only valid when the core is in Host Mode. For Device Mode use USBC_GRXSTSPD instead. | ||
2118 | * NOTE: GRXSTSPH and GRXSTSPD are physically the same register and share the same offset in the O2P USB core. | ||
2119 | * The offset difference shown in this document is for software clarity and is actually ignored by the | ||
2120 | * hardware. | ||
2121 | */ | ||
2122 | union cvmx_usbcx_grxstsph | ||
2123 | { | ||
2124 | uint32_t u32; | ||
2125 | struct cvmx_usbcx_grxstsph_s | ||
2126 | { | ||
2127 | uint32_t reserved_21_31 : 11; | ||
2128 | uint32_t pktsts : 4; /**< Packet Status (PktSts) | ||
2129 | Indicates the status of the received packet | ||
2130 | * 4'b0010: IN data packet received | ||
2131 | * 4'b0011: IN transfer completed (triggers an interrupt) | ||
2132 | * 4'b0101: Data toggle error (triggers an interrupt) | ||
2133 | * 4'b0111: Channel halted (triggers an interrupt) | ||
2134 | * Others: Reserved */ | ||
2135 | uint32_t dpid : 2; /**< Data PID (DPID) | ||
2136 | * 2'b00: DATA0 | ||
2137 | * 2'b10: DATA1 | ||
2138 | * 2'b01: DATA2 | ||
2139 | * 2'b11: MDATA */ | ||
2140 | uint32_t bcnt : 11; /**< Byte Count (BCnt) | ||
2141 | Indicates the byte count of the received IN data packet */ | ||
2142 | uint32_t chnum : 4; /**< Channel Number (ChNum) | ||
2143 | Indicates the channel number to which the current received | ||
2144 | packet belongs. */ | ||
2145 | } s; | ||
2146 | struct cvmx_usbcx_grxstsph_s cn30xx; | ||
2147 | struct cvmx_usbcx_grxstsph_s cn31xx; | ||
2148 | struct cvmx_usbcx_grxstsph_s cn50xx; | ||
2149 | struct cvmx_usbcx_grxstsph_s cn52xx; | ||
2150 | struct cvmx_usbcx_grxstsph_s cn52xxp1; | ||
2151 | struct cvmx_usbcx_grxstsph_s cn56xx; | ||
2152 | struct cvmx_usbcx_grxstsph_s cn56xxp1; | ||
2153 | }; | ||
2154 | typedef union cvmx_usbcx_grxstsph cvmx_usbcx_grxstsph_t; | ||
2155 | |||
2156 | /** | ||
2157 | * cvmx_usbc#_grxstsrd | ||
2158 | * | ||
2159 | * Receive Status Debug Read Register, Device Mode (GRXSTSRD) | ||
2160 | * | ||
2161 | * A read to the Receive Status Debug Read register returns the contents of the top of the Receive FIFO. | ||
2162 | * This Description is only valid when the core is in Device Mode. For Host Mode use USBC_GRXSTSRH instead. | ||
2163 | * NOTE: GRXSTSRH and GRXSTSRD are physically the same register and share the same offset in the O2P USB core. | ||
2164 | * The offset difference shown in this document is for software clarity and is actually ignored by the | ||
2165 | * hardware. | ||
2166 | */ | ||
2167 | union cvmx_usbcx_grxstsrd | ||
2168 | { | ||
2169 | uint32_t u32; | ||
2170 | struct cvmx_usbcx_grxstsrd_s | ||
2171 | { | ||
2172 | uint32_t reserved_25_31 : 7; | ||
2173 | uint32_t fn : 4; /**< Frame Number (FN) | ||
2174 | This is the least significant 4 bits of the (micro)frame number in | ||
2175 | which the packet is received on the USB. This field is supported | ||
2176 | only when the isochronous OUT endpoints are supported. */ | ||
2177 | uint32_t pktsts : 4; /**< Packet Status (PktSts) | ||
2178 | Indicates the status of the received packet | ||
2179 | * 4'b0001: Glogal OUT NAK (triggers an interrupt) | ||
2180 | * 4'b0010: OUT data packet received | ||
2181 | * 4'b0100: SETUP transaction completed (triggers an interrupt) | ||
2182 | * 4'b0110: SETUP data packet received | ||
2183 | * Others: Reserved */ | ||
2184 | uint32_t dpid : 2; /**< Data PID (DPID) | ||
2185 | * 2'b00: DATA0 | ||
2186 | * 2'b10: DATA1 | ||
2187 | * 2'b01: DATA2 | ||
2188 | * 2'b11: MDATA */ | ||
2189 | uint32_t bcnt : 11; /**< Byte Count (BCnt) | ||
2190 | Indicates the byte count of the received data packet */ | ||
2191 | uint32_t epnum : 4; /**< Endpoint Number (EPNum) | ||
2192 | Indicates the endpoint number to which the current received | ||
2193 | packet belongs. */ | ||
2194 | } s; | ||
2195 | struct cvmx_usbcx_grxstsrd_s cn30xx; | ||
2196 | struct cvmx_usbcx_grxstsrd_s cn31xx; | ||
2197 | struct cvmx_usbcx_grxstsrd_s cn50xx; | ||
2198 | struct cvmx_usbcx_grxstsrd_s cn52xx; | ||
2199 | struct cvmx_usbcx_grxstsrd_s cn52xxp1; | ||
2200 | struct cvmx_usbcx_grxstsrd_s cn56xx; | ||
2201 | struct cvmx_usbcx_grxstsrd_s cn56xxp1; | ||
2202 | }; | ||
2203 | typedef union cvmx_usbcx_grxstsrd cvmx_usbcx_grxstsrd_t; | ||
2204 | |||
2205 | /** | ||
2206 | * cvmx_usbc#_grxstsrh | ||
2207 | * | ||
2208 | * Receive Status Debug Read Register, Host Mode (GRXSTSRH) | ||
2209 | * | ||
2210 | * A read to the Receive Status Debug Read register returns the contents of the top of the Receive FIFO. | ||
2211 | * This Description is only valid when the core is in Host Mode. For Device Mode use USBC_GRXSTSRD instead. | ||
2212 | * NOTE: GRXSTSRH and GRXSTSRD are physically the same register and share the same offset in the O2P USB core. | ||
2213 | * The offset difference shown in this document is for software clarity and is actually ignored by the | ||
2214 | * hardware. | ||
2215 | */ | ||
2216 | union cvmx_usbcx_grxstsrh | ||
2217 | { | ||
2218 | uint32_t u32; | ||
2219 | struct cvmx_usbcx_grxstsrh_s | ||
2220 | { | ||
2221 | uint32_t reserved_21_31 : 11; | ||
2222 | uint32_t pktsts : 4; /**< Packet Status (PktSts) | ||
2223 | Indicates the status of the received packet | ||
2224 | * 4'b0010: IN data packet received | ||
2225 | * 4'b0011: IN transfer completed (triggers an interrupt) | ||
2226 | * 4'b0101: Data toggle error (triggers an interrupt) | ||
2227 | * 4'b0111: Channel halted (triggers an interrupt) | ||
2228 | * Others: Reserved */ | ||
2229 | uint32_t dpid : 2; /**< Data PID (DPID) | ||
2230 | * 2'b00: DATA0 | ||
2231 | * 2'b10: DATA1 | ||
2232 | * 2'b01: DATA2 | ||
2233 | * 2'b11: MDATA */ | ||
2234 | uint32_t bcnt : 11; /**< Byte Count (BCnt) | ||
2235 | Indicates the byte count of the received IN data packet */ | ||
2236 | uint32_t chnum : 4; /**< Channel Number (ChNum) | ||
2237 | Indicates the channel number to which the current received | ||
2238 | packet belongs. */ | ||
2239 | } s; | ||
2240 | struct cvmx_usbcx_grxstsrh_s cn30xx; | ||
2241 | struct cvmx_usbcx_grxstsrh_s cn31xx; | ||
2242 | struct cvmx_usbcx_grxstsrh_s cn50xx; | ||
2243 | struct cvmx_usbcx_grxstsrh_s cn52xx; | ||
2244 | struct cvmx_usbcx_grxstsrh_s cn52xxp1; | ||
2245 | struct cvmx_usbcx_grxstsrh_s cn56xx; | ||
2246 | struct cvmx_usbcx_grxstsrh_s cn56xxp1; | ||
2247 | }; | ||
2248 | typedef union cvmx_usbcx_grxstsrh cvmx_usbcx_grxstsrh_t; | ||
2249 | |||
2250 | /** | ||
2251 | * cvmx_usbc#_gsnpsid | ||
2252 | * | ||
2253 | * Synopsys ID Register (GSNPSID) | ||
2254 | * | ||
2255 | * This is a read-only register that contains the release number of the core being used. | ||
2256 | */ | ||
2257 | union cvmx_usbcx_gsnpsid | ||
2258 | { | ||
2259 | uint32_t u32; | ||
2260 | struct cvmx_usbcx_gsnpsid_s | ||
2261 | { | ||
2262 | uint32_t synopsysid : 32; /**< 0x4F54\<version\>A, release number of the core being used. | ||
2263 | 0x4F54220A => pass1.x, 0x4F54240A => pass2.x */ | ||
2264 | } s; | ||
2265 | struct cvmx_usbcx_gsnpsid_s cn30xx; | ||
2266 | struct cvmx_usbcx_gsnpsid_s cn31xx; | ||
2267 | struct cvmx_usbcx_gsnpsid_s cn50xx; | ||
2268 | struct cvmx_usbcx_gsnpsid_s cn52xx; | ||
2269 | struct cvmx_usbcx_gsnpsid_s cn52xxp1; | ||
2270 | struct cvmx_usbcx_gsnpsid_s cn56xx; | ||
2271 | struct cvmx_usbcx_gsnpsid_s cn56xxp1; | ||
2272 | }; | ||
2273 | typedef union cvmx_usbcx_gsnpsid cvmx_usbcx_gsnpsid_t; | ||
2274 | |||
2275 | /** | ||
2276 | * cvmx_usbc#_gusbcfg | ||
2277 | * | ||
2278 | * Core USB Configuration Register (GUSBCFG) | ||
2279 | * | ||
2280 | * This register can be used to configure the core after power-on or a changing to Host mode or Device mode. | ||
2281 | * It contains USB and USB-PHY related configuration parameters. The application must program this register | ||
2282 | * before starting any transactions on either the AHB or the USB. | ||
2283 | * Do not make changes to this register after the initial programming. | ||
2284 | */ | ||
2285 | union cvmx_usbcx_gusbcfg | ||
2286 | { | ||
2287 | uint32_t u32; | ||
2288 | struct cvmx_usbcx_gusbcfg_s | ||
2289 | { | ||
2290 | uint32_t reserved_17_31 : 15; | ||
2291 | uint32_t otgi2csel : 1; /**< UTMIFS or I2C Interface Select (OtgI2CSel) | ||
2292 | This bit is always 0x0. */ | ||
2293 | uint32_t phylpwrclksel : 1; /**< PHY Low-Power Clock Select (PhyLPwrClkSel) | ||
2294 | Software should set this bit to 0x0. | ||
2295 | Selects either 480-MHz or 48-MHz (low-power) PHY mode. In | ||
2296 | FS and LS modes, the PHY can usually operate on a 48-MHz | ||
2297 | clock to save power. | ||
2298 | * 1'b0: 480-MHz Internal PLL clock | ||
2299 | * 1'b1: 48-MHz External Clock | ||
2300 | In 480 MHz mode, the UTMI interface operates at either 60 or | ||
2301 | 30-MHz, depending upon whether 8- or 16-bit data width is | ||
2302 | selected. In 48-MHz mode, the UTMI interface operates at 48 | ||
2303 | MHz in FS mode and at either 48 or 6 MHz in LS mode | ||
2304 | (depending on the PHY vendor). | ||
2305 | This bit drives the utmi_fsls_low_power core output signal, and | ||
2306 | is valid only for UTMI+ PHYs. */ | ||
2307 | uint32_t reserved_14_14 : 1; | ||
2308 | uint32_t usbtrdtim : 4; /**< USB Turnaround Time (USBTrdTim) | ||
2309 | Sets the turnaround time in PHY clocks. | ||
2310 | Specifies the response time for a MAC request to the Packet | ||
2311 | FIFO Controller (PFC) to fetch data from the DFIFO (SPRAM). | ||
2312 | This must be programmed to 0x5. */ | ||
2313 | uint32_t hnpcap : 1; /**< HNP-Capable (HNPCap) | ||
2314 | This bit is always 0x0. */ | ||
2315 | uint32_t srpcap : 1; /**< SRP-Capable (SRPCap) | ||
2316 | This bit is always 0x0. */ | ||
2317 | uint32_t ddrsel : 1; /**< ULPI DDR Select (DDRSel) | ||
2318 | Software should set this bit to 0x0. */ | ||
2319 | uint32_t physel : 1; /**< USB 2.0 High-Speed PHY or USB 1.1 Full-Speed Serial | ||
2320 | Software should set this bit to 0x0. */ | ||
2321 | uint32_t fsintf : 1; /**< Full-Speed Serial Interface Select (FSIntf) | ||
2322 | Software should set this bit to 0x0. */ | ||
2323 | uint32_t ulpi_utmi_sel : 1; /**< ULPI or UTMI+ Select (ULPI_UTMI_Sel) | ||
2324 | This bit is always 0x0. */ | ||
2325 | uint32_t phyif : 1; /**< PHY Interface (PHYIf) | ||
2326 | This bit is always 0x1. */ | ||
2327 | uint32_t toutcal : 3; /**< HS/FS Timeout Calibration (TOutCal) | ||
2328 | The number of PHY clocks that the application programs in this | ||
2329 | field is added to the high-speed/full-speed interpacket timeout | ||
2330 | duration in the core to account for any additional delays | ||
2331 | introduced by the PHY. This may be required, since the delay | ||
2332 | introduced by the PHY in generating the linestate condition may | ||
2333 | vary from one PHY to another. | ||
2334 | The USB standard timeout value for high-speed operation is | ||
2335 | 736 to 816 (inclusive) bit times. The USB standard timeout | ||
2336 | value for full-speed operation is 16 to 18 (inclusive) bit times. | ||
2337 | The application must program this field based on the speed of | ||
2338 | enumeration. The number of bit times added per PHY clock are: | ||
2339 | High-speed operation: | ||
2340 | * One 30-MHz PHY clock = 16 bit times | ||
2341 | * One 60-MHz PHY clock = 8 bit times | ||
2342 | Full-speed operation: | ||
2343 | * One 30-MHz PHY clock = 0.4 bit times | ||
2344 | * One 60-MHz PHY clock = 0.2 bit times | ||
2345 | * One 48-MHz PHY clock = 0.25 bit times */ | ||
2346 | } s; | ||
2347 | struct cvmx_usbcx_gusbcfg_s cn30xx; | ||
2348 | struct cvmx_usbcx_gusbcfg_s cn31xx; | ||
2349 | struct cvmx_usbcx_gusbcfg_s cn50xx; | ||
2350 | struct cvmx_usbcx_gusbcfg_s cn52xx; | ||
2351 | struct cvmx_usbcx_gusbcfg_s cn52xxp1; | ||
2352 | struct cvmx_usbcx_gusbcfg_s cn56xx; | ||
2353 | struct cvmx_usbcx_gusbcfg_s cn56xxp1; | ||
2354 | }; | ||
2355 | typedef union cvmx_usbcx_gusbcfg cvmx_usbcx_gusbcfg_t; | ||
2356 | |||
2357 | /** | ||
2358 | * cvmx_usbc#_haint | ||
2359 | * | ||
2360 | * Host All Channels Interrupt Register (HAINT) | ||
2361 | * | ||
2362 | * When a significant event occurs on a channel, the Host All Channels Interrupt register | ||
2363 | * interrupts the application using the Host Channels Interrupt bit of the Core Interrupt | ||
2364 | * register (GINTSTS.HChInt). This is shown in Interrupt . There is one interrupt bit per | ||
2365 | * channel, up to a maximum of 16 bits. Bits in this register are set and cleared when the | ||
2366 | * application sets and clears bits in the corresponding Host Channel-n Interrupt register. | ||
2367 | */ | ||
2368 | union cvmx_usbcx_haint | ||
2369 | { | ||
2370 | uint32_t u32; | ||
2371 | struct cvmx_usbcx_haint_s | ||
2372 | { | ||
2373 | uint32_t reserved_16_31 : 16; | ||
2374 | uint32_t haint : 16; /**< Channel Interrupts (HAINT) | ||
2375 | One bit per channel: Bit 0 for Channel 0, bit 15 for Channel 15 */ | ||
2376 | } s; | ||
2377 | struct cvmx_usbcx_haint_s cn30xx; | ||
2378 | struct cvmx_usbcx_haint_s cn31xx; | ||
2379 | struct cvmx_usbcx_haint_s cn50xx; | ||
2380 | struct cvmx_usbcx_haint_s cn52xx; | ||
2381 | struct cvmx_usbcx_haint_s cn52xxp1; | ||
2382 | struct cvmx_usbcx_haint_s cn56xx; | ||
2383 | struct cvmx_usbcx_haint_s cn56xxp1; | ||
2384 | }; | ||
2385 | typedef union cvmx_usbcx_haint cvmx_usbcx_haint_t; | ||
2386 | |||
2387 | /** | ||
2388 | * cvmx_usbc#_haintmsk | ||
2389 | * | ||
2390 | * Host All Channels Interrupt Mask Register (HAINTMSK) | ||
2391 | * | ||
2392 | * The Host All Channel Interrupt Mask register works with the Host All Channel Interrupt | ||
2393 | * register to interrupt the application when an event occurs on a channel. There is one | ||
2394 | * interrupt mask bit per channel, up to a maximum of 16 bits. | ||
2395 | * Mask interrupt: 1'b0 Unmask interrupt: 1'b1 | ||
2396 | */ | ||
2397 | union cvmx_usbcx_haintmsk | ||
2398 | { | ||
2399 | uint32_t u32; | ||
2400 | struct cvmx_usbcx_haintmsk_s | ||
2401 | { | ||
2402 | uint32_t reserved_16_31 : 16; | ||
2403 | uint32_t haintmsk : 16; /**< Channel Interrupt Mask (HAINTMsk) | ||
2404 | One bit per channel: Bit 0 for channel 0, bit 15 for channel 15 */ | ||
2405 | } s; | ||
2406 | struct cvmx_usbcx_haintmsk_s cn30xx; | ||
2407 | struct cvmx_usbcx_haintmsk_s cn31xx; | ||
2408 | struct cvmx_usbcx_haintmsk_s cn50xx; | ||
2409 | struct cvmx_usbcx_haintmsk_s cn52xx; | ||
2410 | struct cvmx_usbcx_haintmsk_s cn52xxp1; | ||
2411 | struct cvmx_usbcx_haintmsk_s cn56xx; | ||
2412 | struct cvmx_usbcx_haintmsk_s cn56xxp1; | ||
2413 | }; | ||
2414 | typedef union cvmx_usbcx_haintmsk cvmx_usbcx_haintmsk_t; | ||
2415 | |||
2416 | /** | ||
2417 | * cvmx_usbc#_hcchar# | ||
2418 | * | ||
2419 | * Host Channel-n Characteristics Register (HCCHAR) | ||
2420 | * | ||
2421 | */ | ||
2422 | union cvmx_usbcx_hccharx | ||
2423 | { | ||
2424 | uint32_t u32; | ||
2425 | struct cvmx_usbcx_hccharx_s | ||
2426 | { | ||
2427 | uint32_t chena : 1; /**< Channel Enable (ChEna) | ||
2428 | This field is set by the application and cleared by the OTG host. | ||
2429 | * 1'b0: Channel disabled | ||
2430 | * 1'b1: Channel enabled */ | ||
2431 | uint32_t chdis : 1; /**< Channel Disable (ChDis) | ||
2432 | The application sets this bit to stop transmitting/receiving data | ||
2433 | on a channel, even before the transfer for that channel is | ||
2434 | complete. The application must wait for the Channel Disabled | ||
2435 | interrupt before treating the channel as disabled. */ | ||
2436 | uint32_t oddfrm : 1; /**< Odd Frame (OddFrm) | ||
2437 | This field is set (reset) by the application to indicate that the | ||
2438 | OTG host must perform a transfer in an odd (micro)frame. This | ||
2439 | field is applicable for only periodic (isochronous and interrupt) | ||
2440 | transactions. | ||
2441 | * 1'b0: Even (micro)frame | ||
2442 | * 1'b1: Odd (micro)frame */ | ||
2443 | uint32_t devaddr : 7; /**< Device Address (DevAddr) | ||
2444 | This field selects the specific device serving as the data source | ||
2445 | or sink. */ | ||
2446 | uint32_t ec : 2; /**< Multi Count (MC) / Error Count (EC) | ||
2447 | When the Split Enable bit of the Host Channel-n Split Control | ||
2448 | register (HCSPLTn.SpltEna) is reset (1'b0), this field indicates | ||
2449 | to the host the number of transactions that should be executed | ||
2450 | per microframe for this endpoint. | ||
2451 | * 2'b00: Reserved. This field yields undefined results. | ||
2452 | * 2'b01: 1 transaction | ||
2453 | * 2'b10: 2 transactions to be issued for this endpoint per | ||
2454 | microframe | ||
2455 | * 2'b11: 3 transactions to be issued for this endpoint per | ||
2456 | microframe | ||
2457 | When HCSPLTn.SpltEna is set (1'b1), this field indicates the | ||
2458 | number of immediate retries to be performed for a periodic split | ||
2459 | transactions on transaction errors. This field must be set to at | ||
2460 | least 2'b01. */ | ||
2461 | uint32_t eptype : 2; /**< Endpoint Type (EPType) | ||
2462 | Indicates the transfer type selected. | ||
2463 | * 2'b00: Control | ||
2464 | * 2'b01: Isochronous | ||
2465 | * 2'b10: Bulk | ||
2466 | * 2'b11: Interrupt */ | ||
2467 | uint32_t lspddev : 1; /**< Low-Speed Device (LSpdDev) | ||
2468 | This field is set by the application to indicate that this channel is | ||
2469 | communicating to a low-speed device. */ | ||
2470 | uint32_t reserved_16_16 : 1; | ||
2471 | uint32_t epdir : 1; /**< Endpoint Direction (EPDir) | ||
2472 | Indicates whether the transaction is IN or OUT. | ||
2473 | * 1'b0: OUT | ||
2474 | * 1'b1: IN */ | ||
2475 | uint32_t epnum : 4; /**< Endpoint Number (EPNum) | ||
2476 | Indicates the endpoint number on the device serving as the | ||
2477 | data source or sink. */ | ||
2478 | uint32_t mps : 11; /**< Maximum Packet Size (MPS) | ||
2479 | Indicates the maximum packet size of the associated endpoint. */ | ||
2480 | } s; | ||
2481 | struct cvmx_usbcx_hccharx_s cn30xx; | ||
2482 | struct cvmx_usbcx_hccharx_s cn31xx; | ||
2483 | struct cvmx_usbcx_hccharx_s cn50xx; | ||
2484 | struct cvmx_usbcx_hccharx_s cn52xx; | ||
2485 | struct cvmx_usbcx_hccharx_s cn52xxp1; | ||
2486 | struct cvmx_usbcx_hccharx_s cn56xx; | ||
2487 | struct cvmx_usbcx_hccharx_s cn56xxp1; | ||
2488 | }; | ||
2489 | typedef union cvmx_usbcx_hccharx cvmx_usbcx_hccharx_t; | ||
2490 | |||
2491 | /** | ||
2492 | * cvmx_usbc#_hcfg | ||
2493 | * | ||
2494 | * Host Configuration Register (HCFG) | ||
2495 | * | ||
2496 | * This register configures the core after power-on. Do not make changes to this register after initializing the host. | ||
2497 | */ | ||
2498 | union cvmx_usbcx_hcfg | ||
2499 | { | ||
2500 | uint32_t u32; | ||
2501 | struct cvmx_usbcx_hcfg_s | ||
2502 | { | ||
2503 | uint32_t reserved_3_31 : 29; | ||
2504 | uint32_t fslssupp : 1; /**< FS- and LS-Only Support (FSLSSupp) | ||
2505 | The application uses this bit to control the core's enumeration | ||
2506 | speed. Using this bit, the application can make the core | ||
2507 | enumerate as a FS host, even if the connected device supports | ||
2508 | HS traffic. Do not make changes to this field after initial | ||
2509 | programming. | ||
2510 | * 1'b0: HS/FS/LS, based on the maximum speed supported by | ||
2511 | the connected device | ||
2512 | * 1'b1: FS/LS-only, even if the connected device can support HS */ | ||
2513 | uint32_t fslspclksel : 2; /**< FS/LS PHY Clock Select (FSLSPclkSel) | ||
2514 | When the core is in FS Host mode | ||
2515 | * 2'b00: PHY clock is running at 30/60 MHz | ||
2516 | * 2'b01: PHY clock is running at 48 MHz | ||
2517 | * Others: Reserved | ||
2518 | When the core is in LS Host mode | ||
2519 | * 2'b00: PHY clock is running at 30/60 MHz. When the | ||
2520 | UTMI+/ULPI PHY Low Power mode is not selected, use | ||
2521 | 30/60 MHz. | ||
2522 | * 2'b01: PHY clock is running at 48 MHz. When the UTMI+ | ||
2523 | PHY Low Power mode is selected, use 48MHz if the PHY | ||
2524 | supplies a 48 MHz clock during LS mode. | ||
2525 | * 2'b10: PHY clock is running at 6 MHz. In USB 1.1 FS mode, | ||
2526 | use 6 MHz when the UTMI+ PHY Low Power mode is | ||
2527 | selected and the PHY supplies a 6 MHz clock during LS | ||
2528 | mode. If you select a 6 MHz clock during LS mode, you must | ||
2529 | do a soft reset. | ||
2530 | * 2'b11: Reserved */ | ||
2531 | } s; | ||
2532 | struct cvmx_usbcx_hcfg_s cn30xx; | ||
2533 | struct cvmx_usbcx_hcfg_s cn31xx; | ||
2534 | struct cvmx_usbcx_hcfg_s cn50xx; | ||
2535 | struct cvmx_usbcx_hcfg_s cn52xx; | ||
2536 | struct cvmx_usbcx_hcfg_s cn52xxp1; | ||
2537 | struct cvmx_usbcx_hcfg_s cn56xx; | ||
2538 | struct cvmx_usbcx_hcfg_s cn56xxp1; | ||
2539 | }; | ||
2540 | typedef union cvmx_usbcx_hcfg cvmx_usbcx_hcfg_t; | ||
2541 | |||
2542 | /** | ||
2543 | * cvmx_usbc#_hcint# | ||
2544 | * | ||
2545 | * Host Channel-n Interrupt Register (HCINT) | ||
2546 | * | ||
2547 | * This register indicates the status of a channel with respect to USB- and AHB-related events. | ||
2548 | * The application must read this register when the Host Channels Interrupt bit of the Core Interrupt | ||
2549 | * register (GINTSTS.HChInt) is set. Before the application can read this register, it must first read | ||
2550 | * the Host All Channels Interrupt (HAINT) register to get the exact channel number for the Host Channel-n | ||
2551 | * Interrupt register. The application must clear the appropriate bit in this register to clear the | ||
2552 | * corresponding bits in the HAINT and GINTSTS registers. | ||
2553 | */ | ||
2554 | union cvmx_usbcx_hcintx | ||
2555 | { | ||
2556 | uint32_t u32; | ||
2557 | struct cvmx_usbcx_hcintx_s | ||
2558 | { | ||
2559 | uint32_t reserved_11_31 : 21; | ||
2560 | uint32_t datatglerr : 1; /**< Data Toggle Error (DataTglErr) */ | ||
2561 | uint32_t frmovrun : 1; /**< Frame Overrun (FrmOvrun) */ | ||
2562 | uint32_t bblerr : 1; /**< Babble Error (BblErr) */ | ||
2563 | uint32_t xacterr : 1; /**< Transaction Error (XactErr) */ | ||
2564 | uint32_t nyet : 1; /**< NYET Response Received Interrupt (NYET) */ | ||
2565 | uint32_t ack : 1; /**< ACK Response Received Interrupt (ACK) */ | ||
2566 | uint32_t nak : 1; /**< NAK Response Received Interrupt (NAK) */ | ||
2567 | uint32_t stall : 1; /**< STALL Response Received Interrupt (STALL) */ | ||
2568 | uint32_t ahberr : 1; /**< This bit is always 0x0. */ | ||
2569 | uint32_t chhltd : 1; /**< Channel Halted (ChHltd) | ||
2570 | Indicates the transfer completed abnormally either because of | ||
2571 | any USB transaction error or in response to disable request by | ||
2572 | the application. */ | ||
2573 | uint32_t xfercompl : 1; /**< Transfer Completed (XferCompl) | ||
2574 | Transfer completed normally without any errors. */ | ||
2575 | } s; | ||
2576 | struct cvmx_usbcx_hcintx_s cn30xx; | ||
2577 | struct cvmx_usbcx_hcintx_s cn31xx; | ||
2578 | struct cvmx_usbcx_hcintx_s cn50xx; | ||
2579 | struct cvmx_usbcx_hcintx_s cn52xx; | ||
2580 | struct cvmx_usbcx_hcintx_s cn52xxp1; | ||
2581 | struct cvmx_usbcx_hcintx_s cn56xx; | ||
2582 | struct cvmx_usbcx_hcintx_s cn56xxp1; | ||
2583 | }; | ||
2584 | typedef union cvmx_usbcx_hcintx cvmx_usbcx_hcintx_t; | ||
2585 | |||
2586 | /** | ||
2587 | * cvmx_usbc#_hcintmsk# | ||
2588 | * | ||
2589 | * Host Channel-n Interrupt Mask Register (HCINTMSKn) | ||
2590 | * | ||
2591 | * This register reflects the mask for each channel status described in the previous section. | ||
2592 | * Mask interrupt: 1'b0 Unmask interrupt: 1'b1 | ||
2593 | */ | ||
2594 | union cvmx_usbcx_hcintmskx | ||
2595 | { | ||
2596 | uint32_t u32; | ||
2597 | struct cvmx_usbcx_hcintmskx_s | ||
2598 | { | ||
2599 | uint32_t reserved_11_31 : 21; | ||
2600 | uint32_t datatglerrmsk : 1; /**< Data Toggle Error Mask (DataTglErrMsk) */ | ||
2601 | uint32_t frmovrunmsk : 1; /**< Frame Overrun Mask (FrmOvrunMsk) */ | ||
2602 | uint32_t bblerrmsk : 1; /**< Babble Error Mask (BblErrMsk) */ | ||
2603 | uint32_t xacterrmsk : 1; /**< Transaction Error Mask (XactErrMsk) */ | ||
2604 | uint32_t nyetmsk : 1; /**< NYET Response Received Interrupt Mask (NyetMsk) */ | ||
2605 | uint32_t ackmsk : 1; /**< ACK Response Received Interrupt Mask (AckMsk) */ | ||
2606 | uint32_t nakmsk : 1; /**< NAK Response Received Interrupt Mask (NakMsk) */ | ||
2607 | uint32_t stallmsk : 1; /**< STALL Response Received Interrupt Mask (StallMsk) */ | ||
2608 | uint32_t ahberrmsk : 1; /**< AHB Error Mask (AHBErrMsk) */ | ||
2609 | uint32_t chhltdmsk : 1; /**< Channel Halted Mask (ChHltdMsk) */ | ||
2610 | uint32_t xfercomplmsk : 1; /**< Transfer Completed Mask (XferComplMsk) */ | ||
2611 | } s; | ||
2612 | struct cvmx_usbcx_hcintmskx_s cn30xx; | ||
2613 | struct cvmx_usbcx_hcintmskx_s cn31xx; | ||
2614 | struct cvmx_usbcx_hcintmskx_s cn50xx; | ||
2615 | struct cvmx_usbcx_hcintmskx_s cn52xx; | ||
2616 | struct cvmx_usbcx_hcintmskx_s cn52xxp1; | ||
2617 | struct cvmx_usbcx_hcintmskx_s cn56xx; | ||
2618 | struct cvmx_usbcx_hcintmskx_s cn56xxp1; | ||
2619 | }; | ||
2620 | typedef union cvmx_usbcx_hcintmskx cvmx_usbcx_hcintmskx_t; | ||
2621 | |||
2622 | /** | ||
2623 | * cvmx_usbc#_hcsplt# | ||
2624 | * | ||
2625 | * Host Channel-n Split Control Register (HCSPLT) | ||
2626 | * | ||
2627 | */ | ||
2628 | union cvmx_usbcx_hcspltx | ||
2629 | { | ||
2630 | uint32_t u32; | ||
2631 | struct cvmx_usbcx_hcspltx_s | ||
2632 | { | ||
2633 | uint32_t spltena : 1; /**< Split Enable (SpltEna) | ||
2634 | The application sets this field to indicate that this channel is | ||
2635 | enabled to perform split transactions. */ | ||
2636 | uint32_t reserved_17_30 : 14; | ||
2637 | uint32_t compsplt : 1; /**< Do Complete Split (CompSplt) | ||
2638 | The application sets this field to request the OTG host to | ||
2639 | perform a complete split transaction. */ | ||
2640 | uint32_t xactpos : 2; /**< Transaction Position (XactPos) | ||
2641 | This field is used to determine whether to send all, first, middle, | ||
2642 | or last payloads with each OUT transaction. | ||
2643 | * 2'b11: All. This is the entire data payload is of this transaction | ||
2644 | (which is less than or equal to 188 bytes). | ||
2645 | * 2'b10: Begin. This is the first data payload of this transaction | ||
2646 | (which is larger than 188 bytes). | ||
2647 | * 2'b00: Mid. This is the middle payload of this transaction | ||
2648 | (which is larger than 188 bytes). | ||
2649 | * 2'b01: End. This is the last payload of this transaction (which | ||
2650 | is larger than 188 bytes). */ | ||
2651 | uint32_t hubaddr : 7; /**< Hub Address (HubAddr) | ||
2652 | This field holds the device address of the transaction | ||
2653 | translator's hub. */ | ||
2654 | uint32_t prtaddr : 7; /**< Port Address (PrtAddr) | ||
2655 | This field is the port number of the recipient transaction | ||
2656 | translator. */ | ||
2657 | } s; | ||
2658 | struct cvmx_usbcx_hcspltx_s cn30xx; | ||
2659 | struct cvmx_usbcx_hcspltx_s cn31xx; | ||
2660 | struct cvmx_usbcx_hcspltx_s cn50xx; | ||
2661 | struct cvmx_usbcx_hcspltx_s cn52xx; | ||
2662 | struct cvmx_usbcx_hcspltx_s cn52xxp1; | ||
2663 | struct cvmx_usbcx_hcspltx_s cn56xx; | ||
2664 | struct cvmx_usbcx_hcspltx_s cn56xxp1; | ||
2665 | }; | ||
2666 | typedef union cvmx_usbcx_hcspltx cvmx_usbcx_hcspltx_t; | ||
2667 | |||
2668 | /** | ||
2669 | * cvmx_usbc#_hctsiz# | ||
2670 | * | ||
2671 | * Host Channel-n Transfer Size Register (HCTSIZ) | ||
2672 | * | ||
2673 | */ | ||
2674 | union cvmx_usbcx_hctsizx | ||
2675 | { | ||
2676 | uint32_t u32; | ||
2677 | struct cvmx_usbcx_hctsizx_s | ||
2678 | { | ||
2679 | uint32_t dopng : 1; /**< Do Ping (DoPng) | ||
2680 | Setting this field to 1 directs the host to do PING protocol. */ | ||
2681 | uint32_t pid : 2; /**< PID (Pid) | ||
2682 | The application programs this field with the type of PID to use | ||
2683 | for the initial transaction. The host will maintain this field for the | ||
2684 | rest of the transfer. | ||
2685 | * 2'b00: DATA0 | ||
2686 | * 2'b01: DATA2 | ||
2687 | * 2'b10: DATA1 | ||
2688 | * 2'b11: MDATA (non-control)/SETUP (control) */ | ||
2689 | uint32_t pktcnt : 10; /**< Packet Count (PktCnt) | ||
2690 | This field is programmed by the application with the expected | ||
2691 | number of packets to be transmitted (OUT) or received (IN). | ||
2692 | The host decrements this count on every successful | ||
2693 | transmission or reception of an OUT/IN packet. Once this count | ||
2694 | reaches zero, the application is interrupted to indicate normal | ||
2695 | completion. */ | ||
2696 | uint32_t xfersize : 19; /**< Transfer Size (XferSize) | ||
2697 | For an OUT, this field is the number of data bytes the host will | ||
2698 | send during the transfer. | ||
2699 | For an IN, this field is the buffer size that the application has | ||
2700 | reserved for the transfer. The application is expected to | ||
2701 | program this field as an integer multiple of the maximum packet | ||
2702 | size for IN transactions (periodic and non-periodic). */ | ||
2703 | } s; | ||
2704 | struct cvmx_usbcx_hctsizx_s cn30xx; | ||
2705 | struct cvmx_usbcx_hctsizx_s cn31xx; | ||
2706 | struct cvmx_usbcx_hctsizx_s cn50xx; | ||
2707 | struct cvmx_usbcx_hctsizx_s cn52xx; | ||
2708 | struct cvmx_usbcx_hctsizx_s cn52xxp1; | ||
2709 | struct cvmx_usbcx_hctsizx_s cn56xx; | ||
2710 | struct cvmx_usbcx_hctsizx_s cn56xxp1; | ||
2711 | }; | ||
2712 | typedef union cvmx_usbcx_hctsizx cvmx_usbcx_hctsizx_t; | ||
2713 | |||
2714 | /** | ||
2715 | * cvmx_usbc#_hfir | ||
2716 | * | ||
2717 | * Host Frame Interval Register (HFIR) | ||
2718 | * | ||
2719 | * This register stores the frame interval information for the current speed to which the O2P USB core has enumerated. | ||
2720 | */ | ||
2721 | union cvmx_usbcx_hfir | ||
2722 | { | ||
2723 | uint32_t u32; | ||
2724 | struct cvmx_usbcx_hfir_s | ||
2725 | { | ||
2726 | uint32_t reserved_16_31 : 16; | ||
2727 | uint32_t frint : 16; /**< Frame Interval (FrInt) | ||
2728 | The value that the application programs to this field specifies | ||
2729 | the interval between two consecutive SOFs (FS) or micro- | ||
2730 | SOFs (HS) or Keep-Alive tokens (HS). This field contains the | ||
2731 | number of PHY clocks that constitute the required frame | ||
2732 | interval. The default value set in this field for a FS operation | ||
2733 | when the PHY clock frequency is 60 MHz. The application can | ||
2734 | write a value to this register only after the Port Enable bit of | ||
2735 | the Host Port Control and Status register (HPRT.PrtEnaPort) | ||
2736 | has been set. If no value is programmed, the core calculates | ||
2737 | the value based on the PHY clock specified in the FS/LS PHY | ||
2738 | Clock Select field of the Host Configuration register | ||
2739 | (HCFG.FSLSPclkSel). Do not change the value of this field | ||
2740 | after the initial configuration. | ||
2741 | * 125 us (PHY clock frequency for HS) | ||
2742 | * 1 ms (PHY clock frequency for FS/LS) */ | ||
2743 | } s; | ||
2744 | struct cvmx_usbcx_hfir_s cn30xx; | ||
2745 | struct cvmx_usbcx_hfir_s cn31xx; | ||
2746 | struct cvmx_usbcx_hfir_s cn50xx; | ||
2747 | struct cvmx_usbcx_hfir_s cn52xx; | ||
2748 | struct cvmx_usbcx_hfir_s cn52xxp1; | ||
2749 | struct cvmx_usbcx_hfir_s cn56xx; | ||
2750 | struct cvmx_usbcx_hfir_s cn56xxp1; | ||
2751 | }; | ||
2752 | typedef union cvmx_usbcx_hfir cvmx_usbcx_hfir_t; | ||
2753 | |||
2754 | /** | ||
2755 | * cvmx_usbc#_hfnum | ||
2756 | * | ||
2757 | * Host Frame Number/Frame Time Remaining Register (HFNUM) | ||
2758 | * | ||
2759 | * This register indicates the current frame number. | ||
2760 | * It also indicates the time remaining (in terms of the number of PHY clocks) | ||
2761 | * in the current (micro)frame. | ||
2762 | */ | ||
2763 | union cvmx_usbcx_hfnum | ||
2764 | { | ||
2765 | uint32_t u32; | ||
2766 | struct cvmx_usbcx_hfnum_s | ||
2767 | { | ||
2768 | uint32_t frrem : 16; /**< Frame Time Remaining (FrRem) | ||
2769 | Indicates the amount of time remaining in the current | ||
2770 | microframe (HS) or frame (FS/LS), in terms of PHY clocks. | ||
2771 | This field decrements on each PHY clock. When it reaches | ||
2772 | zero, this field is reloaded with the value in the Frame Interval | ||
2773 | register and a new SOF is transmitted on the USB. */ | ||
2774 | uint32_t frnum : 16; /**< Frame Number (FrNum) | ||
2775 | This field increments when a new SOF is transmitted on the | ||
2776 | USB, and is reset to 0 when it reaches 16'h3FFF. */ | ||
2777 | } s; | ||
2778 | struct cvmx_usbcx_hfnum_s cn30xx; | ||
2779 | struct cvmx_usbcx_hfnum_s cn31xx; | ||
2780 | struct cvmx_usbcx_hfnum_s cn50xx; | ||
2781 | struct cvmx_usbcx_hfnum_s cn52xx; | ||
2782 | struct cvmx_usbcx_hfnum_s cn52xxp1; | ||
2783 | struct cvmx_usbcx_hfnum_s cn56xx; | ||
2784 | struct cvmx_usbcx_hfnum_s cn56xxp1; | ||
2785 | }; | ||
2786 | typedef union cvmx_usbcx_hfnum cvmx_usbcx_hfnum_t; | ||
2787 | |||
2788 | /** | ||
2789 | * cvmx_usbc#_hprt | ||
2790 | * | ||
2791 | * Host Port Control and Status Register (HPRT) | ||
2792 | * | ||
2793 | * This register is available in both Host and Device modes. | ||
2794 | * Currently, the OTG Host supports only one port. | ||
2795 | * A single register holds USB port-related information such as USB reset, enable, suspend, resume, | ||
2796 | * connect status, and test mode for each port. The R_SS_WC bits in this register can trigger an | ||
2797 | * interrupt to the application through the Host Port Interrupt bit of the Core Interrupt | ||
2798 | * register (GINTSTS.PrtInt). On a Port Interrupt, the application must read this register and clear | ||
2799 | * the bit that caused the interrupt. For the R_SS_WC bits, the application must write a 1 to the bit | ||
2800 | * to clear the interrupt. | ||
2801 | */ | ||
2802 | union cvmx_usbcx_hprt | ||
2803 | { | ||
2804 | uint32_t u32; | ||
2805 | struct cvmx_usbcx_hprt_s | ||
2806 | { | ||
2807 | uint32_t reserved_19_31 : 13; | ||
2808 | uint32_t prtspd : 2; /**< Port Speed (PrtSpd) | ||
2809 | Indicates the speed of the device attached to this port. | ||
2810 | * 2'b00: High speed | ||
2811 | * 2'b01: Full speed | ||
2812 | * 2'b10: Low speed | ||
2813 | * 2'b11: Reserved */ | ||
2814 | uint32_t prttstctl : 4; /**< Port Test Control (PrtTstCtl) | ||
2815 | The application writes a nonzero value to this field to put | ||
2816 | the port into a Test mode, and the corresponding pattern is | ||
2817 | signaled on the port. | ||
2818 | * 4'b0000: Test mode disabled | ||
2819 | * 4'b0001: Test_J mode | ||
2820 | * 4'b0010: Test_K mode | ||
2821 | * 4'b0011: Test_SE0_NAK mode | ||
2822 | * 4'b0100: Test_Packet mode | ||
2823 | * 4'b0101: Test_Force_Enable | ||
2824 | * Others: Reserved | ||
2825 | PrtSpd must be zero (i.e. the interface must be in high-speed | ||
2826 | mode) to use the PrtTstCtl test modes. */ | ||
2827 | uint32_t prtpwr : 1; /**< Port Power (PrtPwr) | ||
2828 | The application uses this field to control power to this port, | ||
2829 | and the core clears this bit on an overcurrent condition. | ||
2830 | * 1'b0: Power off | ||
2831 | * 1'b1: Power on */ | ||
2832 | uint32_t prtlnsts : 2; /**< Port Line Status (PrtLnSts) | ||
2833 | Indicates the current logic level USB data lines | ||
2834 | * Bit [10]: Logic level of D- | ||
2835 | * Bit [11]: Logic level of D+ */ | ||
2836 | uint32_t reserved_9_9 : 1; | ||
2837 | uint32_t prtrst : 1; /**< Port Reset (PrtRst) | ||
2838 | When the application sets this bit, a reset sequence is | ||
2839 | started on this port. The application must time the reset | ||
2840 | period and clear this bit after the reset sequence is | ||
2841 | complete. | ||
2842 | * 1'b0: Port not in reset | ||
2843 | * 1'b1: Port in reset | ||
2844 | The application must leave this bit set for at least a | ||
2845 | minimum duration mentioned below to start a reset on the | ||
2846 | port. The application can leave it set for another 10 ms in | ||
2847 | addition to the required minimum duration, before clearing | ||
2848 | the bit, even though there is no maximum limit set by the | ||
2849 | USB standard. | ||
2850 | * High speed: 50 ms | ||
2851 | * Full speed/Low speed: 10 ms */ | ||
2852 | uint32_t prtsusp : 1; /**< Port Suspend (PrtSusp) | ||
2853 | The application sets this bit to put this port in Suspend | ||
2854 | mode. The core only stops sending SOFs when this is set. | ||
2855 | To stop the PHY clock, the application must set the Port | ||
2856 | Clock Stop bit, which will assert the suspend input pin of | ||
2857 | the PHY. | ||
2858 | The read value of this bit reflects the current suspend | ||
2859 | status of the port. This bit is cleared by the core after a | ||
2860 | remote wakeup signal is detected or the application sets | ||
2861 | the Port Reset bit or Port Resume bit in this register or the | ||
2862 | Resume/Remote Wakeup Detected Interrupt bit or | ||
2863 | Disconnect Detected Interrupt bit in the Core Interrupt | ||
2864 | register (GINTSTS.WkUpInt or GINTSTS.DisconnInt, | ||
2865 | respectively). | ||
2866 | * 1'b0: Port not in Suspend mode | ||
2867 | * 1'b1: Port in Suspend mode */ | ||
2868 | uint32_t prtres : 1; /**< Port Resume (PrtRes) | ||
2869 | The application sets this bit to drive resume signaling on | ||
2870 | the port. The core continues to drive the resume signal | ||
2871 | until the application clears this bit. | ||
2872 | If the core detects a USB remote wakeup sequence, as | ||
2873 | indicated by the Port Resume/Remote Wakeup Detected | ||
2874 | Interrupt bit of the Core Interrupt register | ||
2875 | (GINTSTS.WkUpInt), the core starts driving resume | ||
2876 | signaling without application intervention and clears this bit | ||
2877 | when it detects a disconnect condition. The read value of | ||
2878 | this bit indicates whether the core is currently driving | ||
2879 | resume signaling. | ||
2880 | * 1'b0: No resume driven | ||
2881 | * 1'b1: Resume driven */ | ||
2882 | uint32_t prtovrcurrchng : 1; /**< Port Overcurrent Change (PrtOvrCurrChng) | ||
2883 | The core sets this bit when the status of the Port | ||
2884 | Overcurrent Active bit (bit 4) in this register changes. */ | ||
2885 | uint32_t prtovrcurract : 1; /**< Port Overcurrent Active (PrtOvrCurrAct) | ||
2886 | Indicates the overcurrent condition of the port. | ||
2887 | * 1'b0: No overcurrent condition | ||
2888 | * 1'b1: Overcurrent condition */ | ||
2889 | uint32_t prtenchng : 1; /**< Port Enable/Disable Change (PrtEnChng) | ||
2890 | The core sets this bit when the status of the Port Enable bit | ||
2891 | [2] of this register changes. */ | ||
2892 | uint32_t prtena : 1; /**< Port Enable (PrtEna) | ||
2893 | A port is enabled only by the core after a reset sequence, | ||
2894 | and is disabled by an overcurrent condition, a disconnect | ||
2895 | condition, or by the application clearing this bit. The | ||
2896 | application cannot set this bit by a register write. It can only | ||
2897 | clear it to disable the port. This bit does not trigger any | ||
2898 | interrupt to the application. | ||
2899 | * 1'b0: Port disabled | ||
2900 | * 1'b1: Port enabled */ | ||
2901 | uint32_t prtconndet : 1; /**< Port Connect Detected (PrtConnDet) | ||
2902 | The core sets this bit when a device connection is detected | ||
2903 | to trigger an interrupt to the application using the Host Port | ||
2904 | Interrupt bit of the Core Interrupt register (GINTSTS.PrtInt). | ||
2905 | The application must write a 1 to this bit to clear the | ||
2906 | interrupt. */ | ||
2907 | uint32_t prtconnsts : 1; /**< Port Connect Status (PrtConnSts) | ||
2908 | * 0: No device is attached to the port. | ||
2909 | * 1: A device is attached to the port. */ | ||
2910 | } s; | ||
2911 | struct cvmx_usbcx_hprt_s cn30xx; | ||
2912 | struct cvmx_usbcx_hprt_s cn31xx; | ||
2913 | struct cvmx_usbcx_hprt_s cn50xx; | ||
2914 | struct cvmx_usbcx_hprt_s cn52xx; | ||
2915 | struct cvmx_usbcx_hprt_s cn52xxp1; | ||
2916 | struct cvmx_usbcx_hprt_s cn56xx; | ||
2917 | struct cvmx_usbcx_hprt_s cn56xxp1; | ||
2918 | }; | ||
2919 | typedef union cvmx_usbcx_hprt cvmx_usbcx_hprt_t; | ||
2920 | |||
2921 | /** | ||
2922 | * cvmx_usbc#_hptxfsiz | ||
2923 | * | ||
2924 | * Host Periodic Transmit FIFO Size Register (HPTXFSIZ) | ||
2925 | * | ||
2926 | * This register holds the size and the memory start address of the Periodic TxFIFO, as shown in Figures 310 and 311. | ||
2927 | */ | ||
2928 | union cvmx_usbcx_hptxfsiz | ||
2929 | { | ||
2930 | uint32_t u32; | ||
2931 | struct cvmx_usbcx_hptxfsiz_s | ||
2932 | { | ||
2933 | uint32_t ptxfsize : 16; /**< Host Periodic TxFIFO Depth (PTxFSize) | ||
2934 | This value is in terms of 32-bit words. | ||
2935 | * Minimum value is 16 | ||
2936 | * Maximum value is 32768 */ | ||
2937 | uint32_t ptxfstaddr : 16; /**< Host Periodic TxFIFO Start Address (PTxFStAddr) */ | ||
2938 | } s; | ||
2939 | struct cvmx_usbcx_hptxfsiz_s cn30xx; | ||
2940 | struct cvmx_usbcx_hptxfsiz_s cn31xx; | ||
2941 | struct cvmx_usbcx_hptxfsiz_s cn50xx; | ||
2942 | struct cvmx_usbcx_hptxfsiz_s cn52xx; | ||
2943 | struct cvmx_usbcx_hptxfsiz_s cn52xxp1; | ||
2944 | struct cvmx_usbcx_hptxfsiz_s cn56xx; | ||
2945 | struct cvmx_usbcx_hptxfsiz_s cn56xxp1; | ||
2946 | }; | ||
2947 | typedef union cvmx_usbcx_hptxfsiz cvmx_usbcx_hptxfsiz_t; | ||
2948 | |||
2949 | /** | ||
2950 | * cvmx_usbc#_hptxsts | ||
2951 | * | ||
2952 | * Host Periodic Transmit FIFO/Queue Status Register (HPTXSTS) | ||
2953 | * | ||
2954 | * This read-only register contains the free space information for the Periodic TxFIFO and | ||
2955 | * the Periodic Transmit Request Queue | ||
2956 | */ | ||
2957 | union cvmx_usbcx_hptxsts | ||
2958 | { | ||
2959 | uint32_t u32; | ||
2960 | struct cvmx_usbcx_hptxsts_s | ||
2961 | { | ||
2962 | uint32_t ptxqtop : 8; /**< Top of the Periodic Transmit Request Queue (PTxQTop) | ||
2963 | This indicates the entry in the Periodic Tx Request Queue that | ||
2964 | is currently being processes by the MAC. | ||
2965 | This register is used for debugging. | ||
2966 | * Bit [31]: Odd/Even (micro)frame | ||
2967 | - 1'b0: send in even (micro)frame | ||
2968 | - 1'b1: send in odd (micro)frame | ||
2969 | * Bits [30:27]: Channel/endpoint number | ||
2970 | * Bits [26:25]: Type | ||
2971 | - 2'b00: IN/OUT | ||
2972 | - 2'b01: Zero-length packet | ||
2973 | - 2'b10: CSPLIT | ||
2974 | - 2'b11: Disable channel command | ||
2975 | * Bit [24]: Terminate (last entry for the selected | ||
2976 | channel/endpoint) */ | ||
2977 | uint32_t ptxqspcavail : 8; /**< Periodic Transmit Request Queue Space Available | ||
2978 | (PTxQSpcAvail) | ||
2979 | Indicates the number of free locations available to be written in | ||
2980 | the Periodic Transmit Request Queue. This queue holds both | ||
2981 | IN and OUT requests. | ||
2982 | * 8'h0: Periodic Transmit Request Queue is full | ||
2983 | * 8'h1: 1 location available | ||
2984 | * 8'h2: 2 locations available | ||
2985 | * n: n locations available (0..8) | ||
2986 | * Others: Reserved */ | ||
2987 | uint32_t ptxfspcavail : 16; /**< Periodic Transmit Data FIFO Space Available (PTxFSpcAvail) | ||
2988 | Indicates the number of free locations available to be written to | ||
2989 | in the Periodic TxFIFO. | ||
2990 | Values are in terms of 32-bit words | ||
2991 | * 16'h0: Periodic TxFIFO is full | ||
2992 | * 16'h1: 1 word available | ||
2993 | * 16'h2: 2 words available | ||
2994 | * 16'hn: n words available (where 0..32768) | ||
2995 | * 16'h8000: 32768 words available | ||
2996 | * Others: Reserved */ | ||
2997 | } s; | ||
2998 | struct cvmx_usbcx_hptxsts_s cn30xx; | ||
2999 | struct cvmx_usbcx_hptxsts_s cn31xx; | ||
3000 | struct cvmx_usbcx_hptxsts_s cn50xx; | ||
3001 | struct cvmx_usbcx_hptxsts_s cn52xx; | ||
3002 | struct cvmx_usbcx_hptxsts_s cn52xxp1; | ||
3003 | struct cvmx_usbcx_hptxsts_s cn56xx; | ||
3004 | struct cvmx_usbcx_hptxsts_s cn56xxp1; | ||
3005 | }; | ||
3006 | typedef union cvmx_usbcx_hptxsts cvmx_usbcx_hptxsts_t; | ||
3007 | |||
3008 | /** | ||
3009 | * cvmx_usbc#_nptxdfifo# | ||
3010 | * | ||
3011 | * NPTX Data Fifo (NPTXDFIFO) | ||
3012 | * | ||
3013 | * A slave mode application uses this register to access the Tx FIFO for channel n. | ||
3014 | */ | ||
3015 | union cvmx_usbcx_nptxdfifox | ||
3016 | { | ||
3017 | uint32_t u32; | ||
3018 | struct cvmx_usbcx_nptxdfifox_s | ||
3019 | { | ||
3020 | uint32_t data : 32; /**< Reserved */ | ||
3021 | } s; | ||
3022 | struct cvmx_usbcx_nptxdfifox_s cn30xx; | ||
3023 | struct cvmx_usbcx_nptxdfifox_s cn31xx; | ||
3024 | struct cvmx_usbcx_nptxdfifox_s cn50xx; | ||
3025 | struct cvmx_usbcx_nptxdfifox_s cn52xx; | ||
3026 | struct cvmx_usbcx_nptxdfifox_s cn52xxp1; | ||
3027 | struct cvmx_usbcx_nptxdfifox_s cn56xx; | ||
3028 | struct cvmx_usbcx_nptxdfifox_s cn56xxp1; | ||
3029 | }; | ||
3030 | typedef union cvmx_usbcx_nptxdfifox cvmx_usbcx_nptxdfifox_t; | ||
3031 | |||
3032 | /** | ||
3033 | * cvmx_usbc#_pcgcctl | ||
3034 | * | ||
3035 | * Power and Clock Gating Control Register (PCGCCTL) | ||
3036 | * | ||
3037 | * The application can use this register to control the core's power-down and clock gating features. | ||
3038 | */ | ||
3039 | union cvmx_usbcx_pcgcctl | ||
3040 | { | ||
3041 | uint32_t u32; | ||
3042 | struct cvmx_usbcx_pcgcctl_s | ||
3043 | { | ||
3044 | uint32_t reserved_5_31 : 27; | ||
3045 | uint32_t physuspended : 1; /**< PHY Suspended. (PhySuspended) | ||
3046 | Indicates that the PHY has been suspended. After the | ||
3047 | application sets the Stop Pclk bit (bit 0), this bit is updated once | ||
3048 | the PHY is suspended. | ||
3049 | Since the UTMI+ PHY suspend is controlled through a port, the | ||
3050 | UTMI+ PHY is suspended immediately after Stop Pclk is set. | ||
3051 | However, the ULPI PHY takes a few clocks to suspend, | ||
3052 | because the suspend information is conveyed through the ULPI | ||
3053 | protocol to the ULPI PHY. */ | ||
3054 | uint32_t rstpdwnmodule : 1; /**< Reset Power-Down Modules (RstPdwnModule) | ||
3055 | This bit is valid only in Partial Power-Down mode. The | ||
3056 | application sets this bit when the power is turned off. The | ||
3057 | application clears this bit after the power is turned on and the | ||
3058 | PHY clock is up. */ | ||
3059 | uint32_t pwrclmp : 1; /**< Power Clamp (PwrClmp) | ||
3060 | This bit is only valid in Partial Power-Down mode. The | ||
3061 | application sets this bit before the power is turned off to clamp | ||
3062 | the signals between the power-on modules and the power-off | ||
3063 | modules. The application clears the bit to disable the clamping | ||
3064 | before the power is turned on. */ | ||
3065 | uint32_t gatehclk : 1; /**< Gate Hclk (GateHclk) | ||
3066 | The application sets this bit to gate hclk to modules other than | ||
3067 | the AHB Slave and Master and wakeup logic when the USB is | ||
3068 | suspended or the session is not valid. The application clears | ||
3069 | this bit when the USB is resumed or a new session starts. */ | ||
3070 | uint32_t stoppclk : 1; /**< Stop Pclk (StopPclk) | ||
3071 | The application sets this bit to stop the PHY clock (phy_clk) | ||
3072 | when the USB is suspended, the session is not valid, or the | ||
3073 | device is disconnected. The application clears this bit when the | ||
3074 | USB is resumed or a new session starts. */ | ||
3075 | } s; | ||
3076 | struct cvmx_usbcx_pcgcctl_s cn30xx; | ||
3077 | struct cvmx_usbcx_pcgcctl_s cn31xx; | ||
3078 | struct cvmx_usbcx_pcgcctl_s cn50xx; | ||
3079 | struct cvmx_usbcx_pcgcctl_s cn52xx; | ||
3080 | struct cvmx_usbcx_pcgcctl_s cn52xxp1; | ||
3081 | struct cvmx_usbcx_pcgcctl_s cn56xx; | ||
3082 | struct cvmx_usbcx_pcgcctl_s cn56xxp1; | ||
3083 | }; | ||
3084 | typedef union cvmx_usbcx_pcgcctl cvmx_usbcx_pcgcctl_t; | ||
3085 | |||
3086 | #endif | ||
diff --git a/drivers/staging/octeon-usb/cvmx-usbnx-defs.h b/drivers/staging/octeon-usb/cvmx-usbnx-defs.h new file mode 100644 index 000000000000..73ddee08edc1 --- /dev/null +++ b/drivers/staging/octeon-usb/cvmx-usbnx-defs.h | |||
@@ -0,0 +1,1596 @@ | |||
1 | /***********************license start*************** | ||
2 | * Copyright (c) 2003-2010 Cavium Networks (support@cavium.com). All rights | ||
3 | * reserved. | ||
4 | * | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions are | ||
8 | * met: | ||
9 | * | ||
10 | * * Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * | ||
13 | * * Redistributions in binary form must reproduce the above | ||
14 | * copyright notice, this list of conditions and the following | ||
15 | * disclaimer in the documentation and/or other materials provided | ||
16 | * with the distribution. | ||
17 | |||
18 | * * Neither the name of Cavium Networks nor the names of | ||
19 | * its contributors may be used to endorse or promote products | ||
20 | * derived from this software without specific prior written | ||
21 | * permission. | ||
22 | |||
23 | * This Software, including technical data, may be subject to U.S. export control | ||
24 | * laws, including the U.S. Export Administration Act and its associated | ||
25 | * regulations, and may be subject to export or import regulations in other | ||
26 | * countries. | ||
27 | |||
28 | * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" | ||
29 | * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR | ||
30 | * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO | ||
31 | * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR | ||
32 | * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM | ||
33 | * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, | ||
34 | * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF | ||
35 | * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR | ||
36 | * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR | ||
37 | * PERFORMANCE OF THE SOFTWARE LIES WITH YOU. | ||
38 | ***********************license end**************************************/ | ||
39 | |||
40 | |||
41 | /** | ||
42 | * cvmx-usbnx-defs.h | ||
43 | * | ||
44 | * Configuration and status register (CSR) type definitions for | ||
45 | * Octeon usbnx. | ||
46 | * | ||
47 | * This file is auto generated. Do not edit. | ||
48 | * | ||
49 | * <hr>$Revision$<hr> | ||
50 | * | ||
51 | */ | ||
52 | #ifndef __CVMX_USBNX_TYPEDEFS_H__ | ||
53 | #define __CVMX_USBNX_TYPEDEFS_H__ | ||
54 | |||
55 | #define CVMX_USBNX_BIST_STATUS(block_id) (CVMX_ADD_IO_SEG(0x00011800680007F8ull) + ((block_id) & 1) * 0x10000000ull) | ||
56 | #define CVMX_USBNX_CLK_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180068000010ull) + ((block_id) & 1) * 0x10000000ull) | ||
57 | #define CVMX_USBNX_CTL_STATUS(block_id) (CVMX_ADD_IO_SEG(0x00016F0000000800ull) + ((block_id) & 1) * 0x100000000000ull) | ||
58 | #define CVMX_USBNX_DMA0_INB_CHN0(block_id) (CVMX_ADD_IO_SEG(0x00016F0000000818ull) + ((block_id) & 1) * 0x100000000000ull) | ||
59 | #define CVMX_USBNX_DMA0_INB_CHN1(block_id) (CVMX_ADD_IO_SEG(0x00016F0000000820ull) + ((block_id) & 1) * 0x100000000000ull) | ||
60 | #define CVMX_USBNX_DMA0_INB_CHN2(block_id) (CVMX_ADD_IO_SEG(0x00016F0000000828ull) + ((block_id) & 1) * 0x100000000000ull) | ||
61 | #define CVMX_USBNX_DMA0_INB_CHN3(block_id) (CVMX_ADD_IO_SEG(0x00016F0000000830ull) + ((block_id) & 1) * 0x100000000000ull) | ||
62 | #define CVMX_USBNX_DMA0_INB_CHN4(block_id) (CVMX_ADD_IO_SEG(0x00016F0000000838ull) + ((block_id) & 1) * 0x100000000000ull) | ||
63 | #define CVMX_USBNX_DMA0_INB_CHN5(block_id) (CVMX_ADD_IO_SEG(0x00016F0000000840ull) + ((block_id) & 1) * 0x100000000000ull) | ||
64 | #define CVMX_USBNX_DMA0_INB_CHN6(block_id) (CVMX_ADD_IO_SEG(0x00016F0000000848ull) + ((block_id) & 1) * 0x100000000000ull) | ||
65 | #define CVMX_USBNX_DMA0_INB_CHN7(block_id) (CVMX_ADD_IO_SEG(0x00016F0000000850ull) + ((block_id) & 1) * 0x100000000000ull) | ||
66 | #define CVMX_USBNX_DMA0_OUTB_CHN0(block_id) (CVMX_ADD_IO_SEG(0x00016F0000000858ull) + ((block_id) & 1) * 0x100000000000ull) | ||
67 | #define CVMX_USBNX_DMA0_OUTB_CHN1(block_id) (CVMX_ADD_IO_SEG(0x00016F0000000860ull) + ((block_id) & 1) * 0x100000000000ull) | ||
68 | #define CVMX_USBNX_DMA0_OUTB_CHN2(block_id) (CVMX_ADD_IO_SEG(0x00016F0000000868ull) + ((block_id) & 1) * 0x100000000000ull) | ||
69 | #define CVMX_USBNX_DMA0_OUTB_CHN3(block_id) (CVMX_ADD_IO_SEG(0x00016F0000000870ull) + ((block_id) & 1) * 0x100000000000ull) | ||
70 | #define CVMX_USBNX_DMA0_OUTB_CHN4(block_id) (CVMX_ADD_IO_SEG(0x00016F0000000878ull) + ((block_id) & 1) * 0x100000000000ull) | ||
71 | #define CVMX_USBNX_DMA0_OUTB_CHN5(block_id) (CVMX_ADD_IO_SEG(0x00016F0000000880ull) + ((block_id) & 1) * 0x100000000000ull) | ||
72 | #define CVMX_USBNX_DMA0_OUTB_CHN6(block_id) (CVMX_ADD_IO_SEG(0x00016F0000000888ull) + ((block_id) & 1) * 0x100000000000ull) | ||
73 | #define CVMX_USBNX_DMA0_OUTB_CHN7(block_id) (CVMX_ADD_IO_SEG(0x00016F0000000890ull) + ((block_id) & 1) * 0x100000000000ull) | ||
74 | #define CVMX_USBNX_DMA_TEST(block_id) (CVMX_ADD_IO_SEG(0x00016F0000000808ull) + ((block_id) & 1) * 0x100000000000ull) | ||
75 | #define CVMX_USBNX_INT_ENB(block_id) (CVMX_ADD_IO_SEG(0x0001180068000008ull) + ((block_id) & 1) * 0x10000000ull) | ||
76 | #define CVMX_USBNX_INT_SUM(block_id) (CVMX_ADD_IO_SEG(0x0001180068000000ull) + ((block_id) & 1) * 0x10000000ull) | ||
77 | #define CVMX_USBNX_USBP_CTL_STATUS(block_id) (CVMX_ADD_IO_SEG(0x0001180068000018ull) + ((block_id) & 1) * 0x10000000ull) | ||
78 | |||
79 | /** | ||
80 | * cvmx_usbn#_bist_status | ||
81 | * | ||
82 | * USBN_BIST_STATUS = USBN's Control and Status | ||
83 | * | ||
84 | * Contain general control bits and status information for the USBN. | ||
85 | */ | ||
86 | union cvmx_usbnx_bist_status | ||
87 | { | ||
88 | uint64_t u64; | ||
89 | struct cvmx_usbnx_bist_status_s | ||
90 | { | ||
91 | uint64_t reserved_7_63 : 57; | ||
92 | uint64_t u2nc_bis : 1; /**< Bist status U2N CTL FIFO Memory. */ | ||
93 | uint64_t u2nf_bis : 1; /**< Bist status U2N FIFO Memory. */ | ||
94 | uint64_t e2hc_bis : 1; /**< Bist status E2H CTL FIFO Memory. */ | ||
95 | uint64_t n2uf_bis : 1; /**< Bist status N2U FIFO Memory. */ | ||
96 | uint64_t usbc_bis : 1; /**< Bist status USBC FIFO Memory. */ | ||
97 | uint64_t nif_bis : 1; /**< Bist status for Inbound Memory. */ | ||
98 | uint64_t nof_bis : 1; /**< Bist status for Outbound Memory. */ | ||
99 | } s; | ||
100 | struct cvmx_usbnx_bist_status_cn30xx | ||
101 | { | ||
102 | uint64_t reserved_3_63 : 61; | ||
103 | uint64_t usbc_bis : 1; /**< Bist status USBC FIFO Memory. */ | ||
104 | uint64_t nif_bis : 1; /**< Bist status for Inbound Memory. */ | ||
105 | uint64_t nof_bis : 1; /**< Bist status for Outbound Memory. */ | ||
106 | } cn30xx; | ||
107 | struct cvmx_usbnx_bist_status_cn30xx cn31xx; | ||
108 | struct cvmx_usbnx_bist_status_s cn50xx; | ||
109 | struct cvmx_usbnx_bist_status_s cn52xx; | ||
110 | struct cvmx_usbnx_bist_status_s cn52xxp1; | ||
111 | struct cvmx_usbnx_bist_status_s cn56xx; | ||
112 | struct cvmx_usbnx_bist_status_s cn56xxp1; | ||
113 | }; | ||
114 | typedef union cvmx_usbnx_bist_status cvmx_usbnx_bist_status_t; | ||
115 | |||
116 | /** | ||
117 | * cvmx_usbn#_clk_ctl | ||
118 | * | ||
119 | * USBN_CLK_CTL = USBN's Clock Control | ||
120 | * | ||
121 | * This register is used to control the frequency of the hclk and the hreset and phy_rst signals. | ||
122 | */ | ||
123 | union cvmx_usbnx_clk_ctl | ||
124 | { | ||
125 | uint64_t u64; | ||
126 | struct cvmx_usbnx_clk_ctl_s | ||
127 | { | ||
128 | uint64_t reserved_20_63 : 44; | ||
129 | uint64_t divide2 : 2; /**< The 'hclk' used by the USB subsystem is derived | ||
130 | from the eclk. | ||
131 | Also see the field DIVIDE. DIVIDE2<1> must currently | ||
132 | be zero because it is not implemented, so the maximum | ||
133 | ratio of eclk/hclk is currently 16. | ||
134 | The actual divide number for hclk is: | ||
135 | (DIVIDE2 + 1) * (DIVIDE + 1) */ | ||
136 | uint64_t hclk_rst : 1; /**< When this field is '0' the HCLK-DIVIDER used to | ||
137 | generate the hclk in the USB Subsystem is held | ||
138 | in reset. This bit must be set to '0' before | ||
139 | changing the value os DIVIDE in this register. | ||
140 | The reset to the HCLK_DIVIDERis also asserted | ||
141 | when core reset is asserted. */ | ||
142 | uint64_t p_x_on : 1; /**< Force USB-PHY on during suspend. | ||
143 | '1' USB-PHY XO block is powered-down during | ||
144 | suspend. | ||
145 | '0' USB-PHY XO block is powered-up during | ||
146 | suspend. | ||
147 | The value of this field must be set while POR is | ||
148 | active. */ | ||
149 | uint64_t reserved_14_15 : 2; | ||
150 | uint64_t p_com_on : 1; /**< '0' Force USB-PHY XO Bias, Bandgap and PLL to | ||
151 | remain powered in Suspend Mode. | ||
152 | '1' The USB-PHY XO Bias, Bandgap and PLL are | ||
153 | powered down in suspend mode. | ||
154 | The value of this field must be set while POR is | ||
155 | active. */ | ||
156 | uint64_t p_c_sel : 2; /**< Phy clock speed select. | ||
157 | Selects the reference clock / crystal frequency. | ||
158 | '11': Reserved | ||
159 | '10': 48 MHz (reserved when a crystal is used) | ||
160 | '01': 24 MHz (reserved when a crystal is used) | ||
161 | '00': 12 MHz | ||
162 | The value of this field must be set while POR is | ||
163 | active. | ||
164 | NOTE: if a crystal is used as a reference clock, | ||
165 | this field must be set to 12 MHz. */ | ||
166 | uint64_t cdiv_byp : 1; /**< Used to enable the bypass input to the USB_CLK_DIV. */ | ||
167 | uint64_t sd_mode : 2; /**< Scaledown mode for the USBC. Control timing events | ||
168 | in the USBC, for normal operation this must be '0'. */ | ||
169 | uint64_t s_bist : 1; /**< Starts bist on the hclk memories, during the '0' | ||
170 | to '1' transition. */ | ||
171 | uint64_t por : 1; /**< Power On Reset for the PHY. | ||
172 | Resets all the PHYS registers and state machines. */ | ||
173 | uint64_t enable : 1; /**< When '1' allows the generation of the hclk. When | ||
174 | '0' the hclk will not be generated. SEE DIVIDE | ||
175 | field of this register. */ | ||
176 | uint64_t prst : 1; /**< When this field is '0' the reset associated with | ||
177 | the phy_clk functionality in the USB Subsystem is | ||
178 | help in reset. This bit should not be set to '1' | ||
179 | until the time it takes 6 clocks (hclk or phy_clk, | ||
180 | whichever is slower) has passed. Under normal | ||
181 | operation once this bit is set to '1' it should not | ||
182 | be set to '0'. */ | ||
183 | uint64_t hrst : 1; /**< When this field is '0' the reset associated with | ||
184 | the hclk functioanlity in the USB Subsystem is | ||
185 | held in reset.This bit should not be set to '1' | ||
186 | until 12ms after phy_clk is stable. Under normal | ||
187 | operation, once this bit is set to '1' it should | ||
188 | not be set to '0'. */ | ||
189 | uint64_t divide : 3; /**< The frequency of 'hclk' used by the USB subsystem | ||
190 | is the eclk frequency divided by the value of | ||
191 | (DIVIDE2 + 1) * (DIVIDE + 1), also see the field | ||
192 | DIVIDE2 of this register. | ||
193 | The hclk frequency should be less than 125Mhz. | ||
194 | After writing a value to this field the SW should | ||
195 | read the field for the value written. | ||
196 | The ENABLE field of this register should not be set | ||
197 | until AFTER this field is set and then read. */ | ||
198 | } s; | ||
199 | struct cvmx_usbnx_clk_ctl_cn30xx | ||
200 | { | ||
201 | uint64_t reserved_18_63 : 46; | ||
202 | uint64_t hclk_rst : 1; /**< When this field is '0' the HCLK-DIVIDER used to | ||
203 | generate the hclk in the USB Subsystem is held | ||
204 | in reset. This bit must be set to '0' before | ||
205 | changing the value os DIVIDE in this register. | ||
206 | The reset to the HCLK_DIVIDERis also asserted | ||
207 | when core reset is asserted. */ | ||
208 | uint64_t p_x_on : 1; /**< Force USB-PHY on during suspend. | ||
209 | '1' USB-PHY XO block is powered-down during | ||
210 | suspend. | ||
211 | '0' USB-PHY XO block is powered-up during | ||
212 | suspend. | ||
213 | The value of this field must be set while POR is | ||
214 | active. */ | ||
215 | uint64_t p_rclk : 1; /**< Phy refrence clock enable. | ||
216 | '1' The PHY PLL uses the XO block output as a | ||
217 | reference. | ||
218 | '0' Reserved. */ | ||
219 | uint64_t p_xenbn : 1; /**< Phy external clock enable. | ||
220 | '1' The XO block uses the clock from a crystal. | ||
221 | '0' The XO block uses an external clock supplied | ||
222 | on the XO pin. USB_XI should be tied to | ||
223 | ground for this usage. */ | ||
224 | uint64_t p_com_on : 1; /**< '0' Force USB-PHY XO Bias, Bandgap and PLL to | ||
225 | remain powered in Suspend Mode. | ||
226 | '1' The USB-PHY XO Bias, Bandgap and PLL are | ||
227 | powered down in suspend mode. | ||
228 | The value of this field must be set while POR is | ||
229 | active. */ | ||
230 | uint64_t p_c_sel : 2; /**< Phy clock speed select. | ||
231 | Selects the reference clock / crystal frequency. | ||
232 | '11': Reserved | ||
233 | '10': 48 MHz | ||
234 | '01': 24 MHz | ||
235 | '00': 12 MHz | ||
236 | The value of this field must be set while POR is | ||
237 | active. */ | ||
238 | uint64_t cdiv_byp : 1; /**< Used to enable the bypass input to the USB_CLK_DIV. */ | ||
239 | uint64_t sd_mode : 2; /**< Scaledown mode for the USBC. Control timing events | ||
240 | in the USBC, for normal operation this must be '0'. */ | ||
241 | uint64_t s_bist : 1; /**< Starts bist on the hclk memories, during the '0' | ||
242 | to '1' transition. */ | ||
243 | uint64_t por : 1; /**< Power On Reset for the PHY. | ||
244 | Resets all the PHYS registers and state machines. */ | ||
245 | uint64_t enable : 1; /**< When '1' allows the generation of the hclk. When | ||
246 | '0' the hclk will not be generated. */ | ||
247 | uint64_t prst : 1; /**< When this field is '0' the reset associated with | ||
248 | the phy_clk functionality in the USB Subsystem is | ||
249 | help in reset. This bit should not be set to '1' | ||
250 | until the time it takes 6 clocks (hclk or phy_clk, | ||
251 | whichever is slower) has passed. Under normal | ||
252 | operation once this bit is set to '1' it should not | ||
253 | be set to '0'. */ | ||
254 | uint64_t hrst : 1; /**< When this field is '0' the reset associated with | ||
255 | the hclk functioanlity in the USB Subsystem is | ||
256 | held in reset.This bit should not be set to '1' | ||
257 | until 12ms after phy_clk is stable. Under normal | ||
258 | operation, once this bit is set to '1' it should | ||
259 | not be set to '0'. */ | ||
260 | uint64_t divide : 3; /**< The 'hclk' used by the USB subsystem is derived | ||
261 | from the eclk. The eclk will be divided by the | ||
262 | value of this field +1 to determine the hclk | ||
263 | frequency. (Also see HRST of this register). | ||
264 | The hclk frequency must be less than 125 MHz. */ | ||
265 | } cn30xx; | ||
266 | struct cvmx_usbnx_clk_ctl_cn30xx cn31xx; | ||
267 | struct cvmx_usbnx_clk_ctl_cn50xx | ||
268 | { | ||
269 | uint64_t reserved_20_63 : 44; | ||
270 | uint64_t divide2 : 2; /**< The 'hclk' used by the USB subsystem is derived | ||
271 | from the eclk. | ||
272 | Also see the field DIVIDE. DIVIDE2<1> must currently | ||
273 | be zero because it is not implemented, so the maximum | ||
274 | ratio of eclk/hclk is currently 16. | ||
275 | The actual divide number for hclk is: | ||
276 | (DIVIDE2 + 1) * (DIVIDE + 1) */ | ||
277 | uint64_t hclk_rst : 1; /**< When this field is '0' the HCLK-DIVIDER used to | ||
278 | generate the hclk in the USB Subsystem is held | ||
279 | in reset. This bit must be set to '0' before | ||
280 | changing the value os DIVIDE in this register. | ||
281 | The reset to the HCLK_DIVIDERis also asserted | ||
282 | when core reset is asserted. */ | ||
283 | uint64_t reserved_16_16 : 1; | ||
284 | uint64_t p_rtype : 2; /**< PHY reference clock type | ||
285 | '0' The USB-PHY uses a 12MHz crystal as a clock | ||
286 | source at the USB_XO and USB_XI pins | ||
287 | '1' Reserved | ||
288 | '2' The USB_PHY uses 12/24/48MHz 2.5V board clock | ||
289 | at the USB_XO pin. USB_XI should be tied to | ||
290 | ground in this case. | ||
291 | '3' Reserved | ||
292 | (bit 14 was P_XENBN on 3xxx) | ||
293 | (bit 15 was P_RCLK on 3xxx) */ | ||
294 | uint64_t p_com_on : 1; /**< '0' Force USB-PHY XO Bias, Bandgap and PLL to | ||
295 | remain powered in Suspend Mode. | ||
296 | '1' The USB-PHY XO Bias, Bandgap and PLL are | ||
297 | powered down in suspend mode. | ||
298 | The value of this field must be set while POR is | ||
299 | active. */ | ||
300 | uint64_t p_c_sel : 2; /**< Phy clock speed select. | ||
301 | Selects the reference clock / crystal frequency. | ||
302 | '11': Reserved | ||
303 | '10': 48 MHz (reserved when a crystal is used) | ||
304 | '01': 24 MHz (reserved when a crystal is used) | ||
305 | '00': 12 MHz | ||
306 | The value of this field must be set while POR is | ||
307 | active. | ||
308 | NOTE: if a crystal is used as a reference clock, | ||
309 | this field must be set to 12 MHz. */ | ||
310 | uint64_t cdiv_byp : 1; /**< Used to enable the bypass input to the USB_CLK_DIV. */ | ||
311 | uint64_t sd_mode : 2; /**< Scaledown mode for the USBC. Control timing events | ||
312 | in the USBC, for normal operation this must be '0'. */ | ||
313 | uint64_t s_bist : 1; /**< Starts bist on the hclk memories, during the '0' | ||
314 | to '1' transition. */ | ||
315 | uint64_t por : 1; /**< Power On Reset for the PHY. | ||
316 | Resets all the PHYS registers and state machines. */ | ||
317 | uint64_t enable : 1; /**< When '1' allows the generation of the hclk. When | ||
318 | '0' the hclk will not be generated. SEE DIVIDE | ||
319 | field of this register. */ | ||
320 | uint64_t prst : 1; /**< When this field is '0' the reset associated with | ||
321 | the phy_clk functionality in the USB Subsystem is | ||
322 | help in reset. This bit should not be set to '1' | ||
323 | until the time it takes 6 clocks (hclk or phy_clk, | ||
324 | whichever is slower) has passed. Under normal | ||
325 | operation once this bit is set to '1' it should not | ||
326 | be set to '0'. */ | ||
327 | uint64_t hrst : 1; /**< When this field is '0' the reset associated with | ||
328 | the hclk functioanlity in the USB Subsystem is | ||
329 | held in reset.This bit should not be set to '1' | ||
330 | until 12ms after phy_clk is stable. Under normal | ||
331 | operation, once this bit is set to '1' it should | ||
332 | not be set to '0'. */ | ||
333 | uint64_t divide : 3; /**< The frequency of 'hclk' used by the USB subsystem | ||
334 | is the eclk frequency divided by the value of | ||
335 | (DIVIDE2 + 1) * (DIVIDE + 1), also see the field | ||
336 | DIVIDE2 of this register. | ||
337 | The hclk frequency should be less than 125Mhz. | ||
338 | After writing a value to this field the SW should | ||
339 | read the field for the value written. | ||
340 | The ENABLE field of this register should not be set | ||
341 | until AFTER this field is set and then read. */ | ||
342 | } cn50xx; | ||
343 | struct cvmx_usbnx_clk_ctl_cn50xx cn52xx; | ||
344 | struct cvmx_usbnx_clk_ctl_cn50xx cn52xxp1; | ||
345 | struct cvmx_usbnx_clk_ctl_cn50xx cn56xx; | ||
346 | struct cvmx_usbnx_clk_ctl_cn50xx cn56xxp1; | ||
347 | }; | ||
348 | typedef union cvmx_usbnx_clk_ctl cvmx_usbnx_clk_ctl_t; | ||
349 | |||
350 | /** | ||
351 | * cvmx_usbn#_ctl_status | ||
352 | * | ||
353 | * USBN_CTL_STATUS = USBN's Control And Status Register | ||
354 | * | ||
355 | * Contains general control and status information for the USBN block. | ||
356 | */ | ||
357 | union cvmx_usbnx_ctl_status | ||
358 | { | ||
359 | uint64_t u64; | ||
360 | struct cvmx_usbnx_ctl_status_s | ||
361 | { | ||
362 | uint64_t reserved_6_63 : 58; | ||
363 | uint64_t dma_0pag : 1; /**< When '1' sets the DMA engine will set the zero-Page | ||
364 | bit in the L2C store operation to the IOB. */ | ||
365 | uint64_t dma_stt : 1; /**< When '1' sets the DMA engine to use STT operations. */ | ||
366 | uint64_t dma_test : 1; /**< When '1' sets the DMA engine into Test-Mode. | ||
367 | For normal operation this bit should be '0'. */ | ||
368 | uint64_t inv_a2 : 1; /**< When '1' causes the address[2] driven on the AHB | ||
369 | for USB-CORE FIFO access to be inverted. Also data | ||
370 | writen to and read from the AHB will have it byte | ||
371 | order swapped. If the orginal order was A-B-C-D the | ||
372 | new byte order will be D-C-B-A. */ | ||
373 | uint64_t l2c_emod : 2; /**< Endian format for data from/to the L2C. | ||
374 | IN: A-B-C-D-E-F-G-H | ||
375 | OUT0: A-B-C-D-E-F-G-H | ||
376 | OUT1: H-G-F-E-D-C-B-A | ||
377 | OUT2: D-C-B-A-H-G-F-E | ||
378 | OUT3: E-F-G-H-A-B-C-D */ | ||
379 | } s; | ||
380 | struct cvmx_usbnx_ctl_status_s cn30xx; | ||
381 | struct cvmx_usbnx_ctl_status_s cn31xx; | ||
382 | struct cvmx_usbnx_ctl_status_s cn50xx; | ||
383 | struct cvmx_usbnx_ctl_status_s cn52xx; | ||
384 | struct cvmx_usbnx_ctl_status_s cn52xxp1; | ||
385 | struct cvmx_usbnx_ctl_status_s cn56xx; | ||
386 | struct cvmx_usbnx_ctl_status_s cn56xxp1; | ||
387 | }; | ||
388 | typedef union cvmx_usbnx_ctl_status cvmx_usbnx_ctl_status_t; | ||
389 | |||
390 | /** | ||
391 | * cvmx_usbn#_dma0_inb_chn0 | ||
392 | * | ||
393 | * USBN_DMA0_INB_CHN0 = USBN's Inbound DMA for USB0 Channel0 | ||
394 | * | ||
395 | * Contains the starting address for use when USB0 writes to L2C via Channel0. | ||
396 | * Writing of this register sets the base address. | ||
397 | */ | ||
398 | union cvmx_usbnx_dma0_inb_chn0 | ||
399 | { | ||
400 | uint64_t u64; | ||
401 | struct cvmx_usbnx_dma0_inb_chn0_s | ||
402 | { | ||
403 | uint64_t reserved_36_63 : 28; | ||
404 | uint64_t addr : 36; /**< Base address for DMA Write to L2C. */ | ||
405 | } s; | ||
406 | struct cvmx_usbnx_dma0_inb_chn0_s cn30xx; | ||
407 | struct cvmx_usbnx_dma0_inb_chn0_s cn31xx; | ||
408 | struct cvmx_usbnx_dma0_inb_chn0_s cn50xx; | ||
409 | struct cvmx_usbnx_dma0_inb_chn0_s cn52xx; | ||
410 | struct cvmx_usbnx_dma0_inb_chn0_s cn52xxp1; | ||
411 | struct cvmx_usbnx_dma0_inb_chn0_s cn56xx; | ||
412 | struct cvmx_usbnx_dma0_inb_chn0_s cn56xxp1; | ||
413 | }; | ||
414 | typedef union cvmx_usbnx_dma0_inb_chn0 cvmx_usbnx_dma0_inb_chn0_t; | ||
415 | |||
416 | /** | ||
417 | * cvmx_usbn#_dma0_inb_chn1 | ||
418 | * | ||
419 | * USBN_DMA0_INB_CHN1 = USBN's Inbound DMA for USB0 Channel1 | ||
420 | * | ||
421 | * Contains the starting address for use when USB0 writes to L2C via Channel1. | ||
422 | * Writing of this register sets the base address. | ||
423 | */ | ||
424 | union cvmx_usbnx_dma0_inb_chn1 | ||
425 | { | ||
426 | uint64_t u64; | ||
427 | struct cvmx_usbnx_dma0_inb_chn1_s | ||
428 | { | ||
429 | uint64_t reserved_36_63 : 28; | ||
430 | uint64_t addr : 36; /**< Base address for DMA Write to L2C. */ | ||
431 | } s; | ||
432 | struct cvmx_usbnx_dma0_inb_chn1_s cn30xx; | ||
433 | struct cvmx_usbnx_dma0_inb_chn1_s cn31xx; | ||
434 | struct cvmx_usbnx_dma0_inb_chn1_s cn50xx; | ||
435 | struct cvmx_usbnx_dma0_inb_chn1_s cn52xx; | ||
436 | struct cvmx_usbnx_dma0_inb_chn1_s cn52xxp1; | ||
437 | struct cvmx_usbnx_dma0_inb_chn1_s cn56xx; | ||
438 | struct cvmx_usbnx_dma0_inb_chn1_s cn56xxp1; | ||
439 | }; | ||
440 | typedef union cvmx_usbnx_dma0_inb_chn1 cvmx_usbnx_dma0_inb_chn1_t; | ||
441 | |||
442 | /** | ||
443 | * cvmx_usbn#_dma0_inb_chn2 | ||
444 | * | ||
445 | * USBN_DMA0_INB_CHN2 = USBN's Inbound DMA for USB0 Channel2 | ||
446 | * | ||
447 | * Contains the starting address for use when USB0 writes to L2C via Channel2. | ||
448 | * Writing of this register sets the base address. | ||
449 | */ | ||
450 | union cvmx_usbnx_dma0_inb_chn2 | ||
451 | { | ||
452 | uint64_t u64; | ||
453 | struct cvmx_usbnx_dma0_inb_chn2_s | ||
454 | { | ||
455 | uint64_t reserved_36_63 : 28; | ||
456 | uint64_t addr : 36; /**< Base address for DMA Write to L2C. */ | ||
457 | } s; | ||
458 | struct cvmx_usbnx_dma0_inb_chn2_s cn30xx; | ||
459 | struct cvmx_usbnx_dma0_inb_chn2_s cn31xx; | ||
460 | struct cvmx_usbnx_dma0_inb_chn2_s cn50xx; | ||
461 | struct cvmx_usbnx_dma0_inb_chn2_s cn52xx; | ||
462 | struct cvmx_usbnx_dma0_inb_chn2_s cn52xxp1; | ||
463 | struct cvmx_usbnx_dma0_inb_chn2_s cn56xx; | ||
464 | struct cvmx_usbnx_dma0_inb_chn2_s cn56xxp1; | ||
465 | }; | ||
466 | typedef union cvmx_usbnx_dma0_inb_chn2 cvmx_usbnx_dma0_inb_chn2_t; | ||
467 | |||
468 | /** | ||
469 | * cvmx_usbn#_dma0_inb_chn3 | ||
470 | * | ||
471 | * USBN_DMA0_INB_CHN3 = USBN's Inbound DMA for USB0 Channel3 | ||
472 | * | ||
473 | * Contains the starting address for use when USB0 writes to L2C via Channel3. | ||
474 | * Writing of this register sets the base address. | ||
475 | */ | ||
476 | union cvmx_usbnx_dma0_inb_chn3 | ||
477 | { | ||
478 | uint64_t u64; | ||
479 | struct cvmx_usbnx_dma0_inb_chn3_s | ||
480 | { | ||
481 | uint64_t reserved_36_63 : 28; | ||
482 | uint64_t addr : 36; /**< Base address for DMA Write to L2C. */ | ||
483 | } s; | ||
484 | struct cvmx_usbnx_dma0_inb_chn3_s cn30xx; | ||
485 | struct cvmx_usbnx_dma0_inb_chn3_s cn31xx; | ||
486 | struct cvmx_usbnx_dma0_inb_chn3_s cn50xx; | ||
487 | struct cvmx_usbnx_dma0_inb_chn3_s cn52xx; | ||
488 | struct cvmx_usbnx_dma0_inb_chn3_s cn52xxp1; | ||
489 | struct cvmx_usbnx_dma0_inb_chn3_s cn56xx; | ||
490 | struct cvmx_usbnx_dma0_inb_chn3_s cn56xxp1; | ||
491 | }; | ||
492 | typedef union cvmx_usbnx_dma0_inb_chn3 cvmx_usbnx_dma0_inb_chn3_t; | ||
493 | |||
494 | /** | ||
495 | * cvmx_usbn#_dma0_inb_chn4 | ||
496 | * | ||
497 | * USBN_DMA0_INB_CHN4 = USBN's Inbound DMA for USB0 Channel4 | ||
498 | * | ||
499 | * Contains the starting address for use when USB0 writes to L2C via Channel4. | ||
500 | * Writing of this register sets the base address. | ||
501 | */ | ||
502 | union cvmx_usbnx_dma0_inb_chn4 | ||
503 | { | ||
504 | uint64_t u64; | ||
505 | struct cvmx_usbnx_dma0_inb_chn4_s | ||
506 | { | ||
507 | uint64_t reserved_36_63 : 28; | ||
508 | uint64_t addr : 36; /**< Base address for DMA Write to L2C. */ | ||
509 | } s; | ||
510 | struct cvmx_usbnx_dma0_inb_chn4_s cn30xx; | ||
511 | struct cvmx_usbnx_dma0_inb_chn4_s cn31xx; | ||
512 | struct cvmx_usbnx_dma0_inb_chn4_s cn50xx; | ||
513 | struct cvmx_usbnx_dma0_inb_chn4_s cn52xx; | ||
514 | struct cvmx_usbnx_dma0_inb_chn4_s cn52xxp1; | ||
515 | struct cvmx_usbnx_dma0_inb_chn4_s cn56xx; | ||
516 | struct cvmx_usbnx_dma0_inb_chn4_s cn56xxp1; | ||
517 | }; | ||
518 | typedef union cvmx_usbnx_dma0_inb_chn4 cvmx_usbnx_dma0_inb_chn4_t; | ||
519 | |||
520 | /** | ||
521 | * cvmx_usbn#_dma0_inb_chn5 | ||
522 | * | ||
523 | * USBN_DMA0_INB_CHN5 = USBN's Inbound DMA for USB0 Channel5 | ||
524 | * | ||
525 | * Contains the starting address for use when USB0 writes to L2C via Channel5. | ||
526 | * Writing of this register sets the base address. | ||
527 | */ | ||
528 | union cvmx_usbnx_dma0_inb_chn5 | ||
529 | { | ||
530 | uint64_t u64; | ||
531 | struct cvmx_usbnx_dma0_inb_chn5_s | ||
532 | { | ||
533 | uint64_t reserved_36_63 : 28; | ||
534 | uint64_t addr : 36; /**< Base address for DMA Write to L2C. */ | ||
535 | } s; | ||
536 | struct cvmx_usbnx_dma0_inb_chn5_s cn30xx; | ||
537 | struct cvmx_usbnx_dma0_inb_chn5_s cn31xx; | ||
538 | struct cvmx_usbnx_dma0_inb_chn5_s cn50xx; | ||
539 | struct cvmx_usbnx_dma0_inb_chn5_s cn52xx; | ||
540 | struct cvmx_usbnx_dma0_inb_chn5_s cn52xxp1; | ||
541 | struct cvmx_usbnx_dma0_inb_chn5_s cn56xx; | ||
542 | struct cvmx_usbnx_dma0_inb_chn5_s cn56xxp1; | ||
543 | }; | ||
544 | typedef union cvmx_usbnx_dma0_inb_chn5 cvmx_usbnx_dma0_inb_chn5_t; | ||
545 | |||
546 | /** | ||
547 | * cvmx_usbn#_dma0_inb_chn6 | ||
548 | * | ||
549 | * USBN_DMA0_INB_CHN6 = USBN's Inbound DMA for USB0 Channel6 | ||
550 | * | ||
551 | * Contains the starting address for use when USB0 writes to L2C via Channel6. | ||
552 | * Writing of this register sets the base address. | ||
553 | */ | ||
554 | union cvmx_usbnx_dma0_inb_chn6 | ||
555 | { | ||
556 | uint64_t u64; | ||
557 | struct cvmx_usbnx_dma0_inb_chn6_s | ||
558 | { | ||
559 | uint64_t reserved_36_63 : 28; | ||
560 | uint64_t addr : 36; /**< Base address for DMA Write to L2C. */ | ||
561 | } s; | ||
562 | struct cvmx_usbnx_dma0_inb_chn6_s cn30xx; | ||
563 | struct cvmx_usbnx_dma0_inb_chn6_s cn31xx; | ||
564 | struct cvmx_usbnx_dma0_inb_chn6_s cn50xx; | ||
565 | struct cvmx_usbnx_dma0_inb_chn6_s cn52xx; | ||
566 | struct cvmx_usbnx_dma0_inb_chn6_s cn52xxp1; | ||
567 | struct cvmx_usbnx_dma0_inb_chn6_s cn56xx; | ||
568 | struct cvmx_usbnx_dma0_inb_chn6_s cn56xxp1; | ||
569 | }; | ||
570 | typedef union cvmx_usbnx_dma0_inb_chn6 cvmx_usbnx_dma0_inb_chn6_t; | ||
571 | |||
572 | /** | ||
573 | * cvmx_usbn#_dma0_inb_chn7 | ||
574 | * | ||
575 | * USBN_DMA0_INB_CHN7 = USBN's Inbound DMA for USB0 Channel7 | ||
576 | * | ||
577 | * Contains the starting address for use when USB0 writes to L2C via Channel7. | ||
578 | * Writing of this register sets the base address. | ||
579 | */ | ||
580 | union cvmx_usbnx_dma0_inb_chn7 | ||
581 | { | ||
582 | uint64_t u64; | ||
583 | struct cvmx_usbnx_dma0_inb_chn7_s | ||
584 | { | ||
585 | uint64_t reserved_36_63 : 28; | ||
586 | uint64_t addr : 36; /**< Base address for DMA Write to L2C. */ | ||
587 | } s; | ||
588 | struct cvmx_usbnx_dma0_inb_chn7_s cn30xx; | ||
589 | struct cvmx_usbnx_dma0_inb_chn7_s cn31xx; | ||
590 | struct cvmx_usbnx_dma0_inb_chn7_s cn50xx; | ||
591 | struct cvmx_usbnx_dma0_inb_chn7_s cn52xx; | ||
592 | struct cvmx_usbnx_dma0_inb_chn7_s cn52xxp1; | ||
593 | struct cvmx_usbnx_dma0_inb_chn7_s cn56xx; | ||
594 | struct cvmx_usbnx_dma0_inb_chn7_s cn56xxp1; | ||
595 | }; | ||
596 | typedef union cvmx_usbnx_dma0_inb_chn7 cvmx_usbnx_dma0_inb_chn7_t; | ||
597 | |||
598 | /** | ||
599 | * cvmx_usbn#_dma0_outb_chn0 | ||
600 | * | ||
601 | * USBN_DMA0_OUTB_CHN0 = USBN's Outbound DMA for USB0 Channel0 | ||
602 | * | ||
603 | * Contains the starting address for use when USB0 reads from L2C via Channel0. | ||
604 | * Writing of this register sets the base address. | ||
605 | */ | ||
606 | union cvmx_usbnx_dma0_outb_chn0 | ||
607 | { | ||
608 | uint64_t u64; | ||
609 | struct cvmx_usbnx_dma0_outb_chn0_s | ||
610 | { | ||
611 | uint64_t reserved_36_63 : 28; | ||
612 | uint64_t addr : 36; /**< Base address for DMA Read from L2C. */ | ||
613 | } s; | ||
614 | struct cvmx_usbnx_dma0_outb_chn0_s cn30xx; | ||
615 | struct cvmx_usbnx_dma0_outb_chn0_s cn31xx; | ||
616 | struct cvmx_usbnx_dma0_outb_chn0_s cn50xx; | ||
617 | struct cvmx_usbnx_dma0_outb_chn0_s cn52xx; | ||
618 | struct cvmx_usbnx_dma0_outb_chn0_s cn52xxp1; | ||
619 | struct cvmx_usbnx_dma0_outb_chn0_s cn56xx; | ||
620 | struct cvmx_usbnx_dma0_outb_chn0_s cn56xxp1; | ||
621 | }; | ||
622 | typedef union cvmx_usbnx_dma0_outb_chn0 cvmx_usbnx_dma0_outb_chn0_t; | ||
623 | |||
624 | /** | ||
625 | * cvmx_usbn#_dma0_outb_chn1 | ||
626 | * | ||
627 | * USBN_DMA0_OUTB_CHN1 = USBN's Outbound DMA for USB0 Channel1 | ||
628 | * | ||
629 | * Contains the starting address for use when USB0 reads from L2C via Channel1. | ||
630 | * Writing of this register sets the base address. | ||
631 | */ | ||
632 | union cvmx_usbnx_dma0_outb_chn1 | ||
633 | { | ||
634 | uint64_t u64; | ||
635 | struct cvmx_usbnx_dma0_outb_chn1_s | ||
636 | { | ||
637 | uint64_t reserved_36_63 : 28; | ||
638 | uint64_t addr : 36; /**< Base address for DMA Read from L2C. */ | ||
639 | } s; | ||
640 | struct cvmx_usbnx_dma0_outb_chn1_s cn30xx; | ||
641 | struct cvmx_usbnx_dma0_outb_chn1_s cn31xx; | ||
642 | struct cvmx_usbnx_dma0_outb_chn1_s cn50xx; | ||
643 | struct cvmx_usbnx_dma0_outb_chn1_s cn52xx; | ||
644 | struct cvmx_usbnx_dma0_outb_chn1_s cn52xxp1; | ||
645 | struct cvmx_usbnx_dma0_outb_chn1_s cn56xx; | ||
646 | struct cvmx_usbnx_dma0_outb_chn1_s cn56xxp1; | ||
647 | }; | ||
648 | typedef union cvmx_usbnx_dma0_outb_chn1 cvmx_usbnx_dma0_outb_chn1_t; | ||
649 | |||
650 | /** | ||
651 | * cvmx_usbn#_dma0_outb_chn2 | ||
652 | * | ||
653 | * USBN_DMA0_OUTB_CHN2 = USBN's Outbound DMA for USB0 Channel2 | ||
654 | * | ||
655 | * Contains the starting address for use when USB0 reads from L2C via Channel2. | ||
656 | * Writing of this register sets the base address. | ||
657 | */ | ||
658 | union cvmx_usbnx_dma0_outb_chn2 | ||
659 | { | ||
660 | uint64_t u64; | ||
661 | struct cvmx_usbnx_dma0_outb_chn2_s | ||
662 | { | ||
663 | uint64_t reserved_36_63 : 28; | ||
664 | uint64_t addr : 36; /**< Base address for DMA Read from L2C. */ | ||
665 | } s; | ||
666 | struct cvmx_usbnx_dma0_outb_chn2_s cn30xx; | ||
667 | struct cvmx_usbnx_dma0_outb_chn2_s cn31xx; | ||
668 | struct cvmx_usbnx_dma0_outb_chn2_s cn50xx; | ||
669 | struct cvmx_usbnx_dma0_outb_chn2_s cn52xx; | ||
670 | struct cvmx_usbnx_dma0_outb_chn2_s cn52xxp1; | ||
671 | struct cvmx_usbnx_dma0_outb_chn2_s cn56xx; | ||
672 | struct cvmx_usbnx_dma0_outb_chn2_s cn56xxp1; | ||
673 | }; | ||
674 | typedef union cvmx_usbnx_dma0_outb_chn2 cvmx_usbnx_dma0_outb_chn2_t; | ||
675 | |||
676 | /** | ||
677 | * cvmx_usbn#_dma0_outb_chn3 | ||
678 | * | ||
679 | * USBN_DMA0_OUTB_CHN3 = USBN's Outbound DMA for USB0 Channel3 | ||
680 | * | ||
681 | * Contains the starting address for use when USB0 reads from L2C via Channel3. | ||
682 | * Writing of this register sets the base address. | ||
683 | */ | ||
684 | union cvmx_usbnx_dma0_outb_chn3 | ||
685 | { | ||
686 | uint64_t u64; | ||
687 | struct cvmx_usbnx_dma0_outb_chn3_s | ||
688 | { | ||
689 | uint64_t reserved_36_63 : 28; | ||
690 | uint64_t addr : 36; /**< Base address for DMA Read from L2C. */ | ||
691 | } s; | ||
692 | struct cvmx_usbnx_dma0_outb_chn3_s cn30xx; | ||
693 | struct cvmx_usbnx_dma0_outb_chn3_s cn31xx; | ||
694 | struct cvmx_usbnx_dma0_outb_chn3_s cn50xx; | ||
695 | struct cvmx_usbnx_dma0_outb_chn3_s cn52xx; | ||
696 | struct cvmx_usbnx_dma0_outb_chn3_s cn52xxp1; | ||
697 | struct cvmx_usbnx_dma0_outb_chn3_s cn56xx; | ||
698 | struct cvmx_usbnx_dma0_outb_chn3_s cn56xxp1; | ||
699 | }; | ||
700 | typedef union cvmx_usbnx_dma0_outb_chn3 cvmx_usbnx_dma0_outb_chn3_t; | ||
701 | |||
702 | /** | ||
703 | * cvmx_usbn#_dma0_outb_chn4 | ||
704 | * | ||
705 | * USBN_DMA0_OUTB_CHN4 = USBN's Outbound DMA for USB0 Channel4 | ||
706 | * | ||
707 | * Contains the starting address for use when USB0 reads from L2C via Channel4. | ||
708 | * Writing of this register sets the base address. | ||
709 | */ | ||
710 | union cvmx_usbnx_dma0_outb_chn4 | ||
711 | { | ||
712 | uint64_t u64; | ||
713 | struct cvmx_usbnx_dma0_outb_chn4_s | ||
714 | { | ||
715 | uint64_t reserved_36_63 : 28; | ||
716 | uint64_t addr : 36; /**< Base address for DMA Read from L2C. */ | ||
717 | } s; | ||
718 | struct cvmx_usbnx_dma0_outb_chn4_s cn30xx; | ||
719 | struct cvmx_usbnx_dma0_outb_chn4_s cn31xx; | ||
720 | struct cvmx_usbnx_dma0_outb_chn4_s cn50xx; | ||
721 | struct cvmx_usbnx_dma0_outb_chn4_s cn52xx; | ||
722 | struct cvmx_usbnx_dma0_outb_chn4_s cn52xxp1; | ||
723 | struct cvmx_usbnx_dma0_outb_chn4_s cn56xx; | ||
724 | struct cvmx_usbnx_dma0_outb_chn4_s cn56xxp1; | ||
725 | }; | ||
726 | typedef union cvmx_usbnx_dma0_outb_chn4 cvmx_usbnx_dma0_outb_chn4_t; | ||
727 | |||
728 | /** | ||
729 | * cvmx_usbn#_dma0_outb_chn5 | ||
730 | * | ||
731 | * USBN_DMA0_OUTB_CHN5 = USBN's Outbound DMA for USB0 Channel5 | ||
732 | * | ||
733 | * Contains the starting address for use when USB0 reads from L2C via Channel5. | ||
734 | * Writing of this register sets the base address. | ||
735 | */ | ||
736 | union cvmx_usbnx_dma0_outb_chn5 | ||
737 | { | ||
738 | uint64_t u64; | ||
739 | struct cvmx_usbnx_dma0_outb_chn5_s | ||
740 | { | ||
741 | uint64_t reserved_36_63 : 28; | ||
742 | uint64_t addr : 36; /**< Base address for DMA Read from L2C. */ | ||
743 | } s; | ||
744 | struct cvmx_usbnx_dma0_outb_chn5_s cn30xx; | ||
745 | struct cvmx_usbnx_dma0_outb_chn5_s cn31xx; | ||
746 | struct cvmx_usbnx_dma0_outb_chn5_s cn50xx; | ||
747 | struct cvmx_usbnx_dma0_outb_chn5_s cn52xx; | ||
748 | struct cvmx_usbnx_dma0_outb_chn5_s cn52xxp1; | ||
749 | struct cvmx_usbnx_dma0_outb_chn5_s cn56xx; | ||
750 | struct cvmx_usbnx_dma0_outb_chn5_s cn56xxp1; | ||
751 | }; | ||
752 | typedef union cvmx_usbnx_dma0_outb_chn5 cvmx_usbnx_dma0_outb_chn5_t; | ||
753 | |||
754 | /** | ||
755 | * cvmx_usbn#_dma0_outb_chn6 | ||
756 | * | ||
757 | * USBN_DMA0_OUTB_CHN6 = USBN's Outbound DMA for USB0 Channel6 | ||
758 | * | ||
759 | * Contains the starting address for use when USB0 reads from L2C via Channel6. | ||
760 | * Writing of this register sets the base address. | ||
761 | */ | ||
762 | union cvmx_usbnx_dma0_outb_chn6 | ||
763 | { | ||
764 | uint64_t u64; | ||
765 | struct cvmx_usbnx_dma0_outb_chn6_s | ||
766 | { | ||
767 | uint64_t reserved_36_63 : 28; | ||
768 | uint64_t addr : 36; /**< Base address for DMA Read from L2C. */ | ||
769 | } s; | ||
770 | struct cvmx_usbnx_dma0_outb_chn6_s cn30xx; | ||
771 | struct cvmx_usbnx_dma0_outb_chn6_s cn31xx; | ||
772 | struct cvmx_usbnx_dma0_outb_chn6_s cn50xx; | ||
773 | struct cvmx_usbnx_dma0_outb_chn6_s cn52xx; | ||
774 | struct cvmx_usbnx_dma0_outb_chn6_s cn52xxp1; | ||
775 | struct cvmx_usbnx_dma0_outb_chn6_s cn56xx; | ||
776 | struct cvmx_usbnx_dma0_outb_chn6_s cn56xxp1; | ||
777 | }; | ||
778 | typedef union cvmx_usbnx_dma0_outb_chn6 cvmx_usbnx_dma0_outb_chn6_t; | ||
779 | |||
780 | /** | ||
781 | * cvmx_usbn#_dma0_outb_chn7 | ||
782 | * | ||
783 | * USBN_DMA0_OUTB_CHN7 = USBN's Outbound DMA for USB0 Channel7 | ||
784 | * | ||
785 | * Contains the starting address for use when USB0 reads from L2C via Channel7. | ||
786 | * Writing of this register sets the base address. | ||
787 | */ | ||
788 | union cvmx_usbnx_dma0_outb_chn7 | ||
789 | { | ||
790 | uint64_t u64; | ||
791 | struct cvmx_usbnx_dma0_outb_chn7_s | ||
792 | { | ||
793 | uint64_t reserved_36_63 : 28; | ||
794 | uint64_t addr : 36; /**< Base address for DMA Read from L2C. */ | ||
795 | } s; | ||
796 | struct cvmx_usbnx_dma0_outb_chn7_s cn30xx; | ||
797 | struct cvmx_usbnx_dma0_outb_chn7_s cn31xx; | ||
798 | struct cvmx_usbnx_dma0_outb_chn7_s cn50xx; | ||
799 | struct cvmx_usbnx_dma0_outb_chn7_s cn52xx; | ||
800 | struct cvmx_usbnx_dma0_outb_chn7_s cn52xxp1; | ||
801 | struct cvmx_usbnx_dma0_outb_chn7_s cn56xx; | ||
802 | struct cvmx_usbnx_dma0_outb_chn7_s cn56xxp1; | ||
803 | }; | ||
804 | typedef union cvmx_usbnx_dma0_outb_chn7 cvmx_usbnx_dma0_outb_chn7_t; | ||
805 | |||
806 | /** | ||
807 | * cvmx_usbn#_dma_test | ||
808 | * | ||
809 | * USBN_DMA_TEST = USBN's DMA TestRegister | ||
810 | * | ||
811 | * This register can cause the external DMA engine to the USB-Core to make transfers from/to L2C/USB-FIFOs | ||
812 | */ | ||
813 | union cvmx_usbnx_dma_test | ||
814 | { | ||
815 | uint64_t u64; | ||
816 | struct cvmx_usbnx_dma_test_s | ||
817 | { | ||
818 | uint64_t reserved_40_63 : 24; | ||
819 | uint64_t done : 1; /**< This field is set when a DMA completes. Writing a | ||
820 | '1' to this field clears this bit. */ | ||
821 | uint64_t req : 1; /**< DMA Request. Writing a 1 to this register | ||
822 | will cause a DMA request as specified in the other | ||
823 | fields of this register to take place. This field | ||
824 | will always read as '0'. */ | ||
825 | uint64_t f_addr : 18; /**< The address to read from in the Data-Fifo. */ | ||
826 | uint64_t count : 11; /**< DMA Request Count. */ | ||
827 | uint64_t channel : 5; /**< DMA Channel/Enpoint. */ | ||
828 | uint64_t burst : 4; /**< DMA Burst Size. */ | ||
829 | } s; | ||
830 | struct cvmx_usbnx_dma_test_s cn30xx; | ||
831 | struct cvmx_usbnx_dma_test_s cn31xx; | ||
832 | struct cvmx_usbnx_dma_test_s cn50xx; | ||
833 | struct cvmx_usbnx_dma_test_s cn52xx; | ||
834 | struct cvmx_usbnx_dma_test_s cn52xxp1; | ||
835 | struct cvmx_usbnx_dma_test_s cn56xx; | ||
836 | struct cvmx_usbnx_dma_test_s cn56xxp1; | ||
837 | }; | ||
838 | typedef union cvmx_usbnx_dma_test cvmx_usbnx_dma_test_t; | ||
839 | |||
840 | /** | ||
841 | * cvmx_usbn#_int_enb | ||
842 | * | ||
843 | * USBN_INT_ENB = USBN's Interrupt Enable | ||
844 | * | ||
845 | * The USBN's interrupt enable register. | ||
846 | */ | ||
847 | union cvmx_usbnx_int_enb | ||
848 | { | ||
849 | uint64_t u64; | ||
850 | struct cvmx_usbnx_int_enb_s | ||
851 | { | ||
852 | uint64_t reserved_38_63 : 26; | ||
853 | uint64_t nd4o_dpf : 1; /**< When set (1) and bit 37 of the USBN_INT_SUM | ||
854 | register is asserted the USBN will assert an | ||
855 | interrupt. */ | ||
856 | uint64_t nd4o_dpe : 1; /**< When set (1) and bit 36 of the USBN_INT_SUM | ||
857 | register is asserted the USBN will assert an | ||
858 | interrupt. */ | ||
859 | uint64_t nd4o_rpf : 1; /**< When set (1) and bit 35 of the USBN_INT_SUM | ||
860 | register is asserted the USBN will assert an | ||
861 | interrupt. */ | ||
862 | uint64_t nd4o_rpe : 1; /**< When set (1) and bit 34 of the USBN_INT_SUM | ||
863 | register is asserted the USBN will assert an | ||
864 | interrupt. */ | ||
865 | uint64_t ltl_f_pf : 1; /**< When set (1) and bit 33 of the USBN_INT_SUM | ||
866 | register is asserted the USBN will assert an | ||
867 | interrupt. */ | ||
868 | uint64_t ltl_f_pe : 1; /**< When set (1) and bit 32 of the USBN_INT_SUM | ||
869 | register is asserted the USBN will assert an | ||
870 | interrupt. */ | ||
871 | uint64_t u2n_c_pe : 1; /**< When set (1) and bit 31 of the USBN_INT_SUM | ||
872 | register is asserted the USBN will assert an | ||
873 | interrupt. */ | ||
874 | uint64_t u2n_c_pf : 1; /**< When set (1) and bit 30 of the USBN_INT_SUM | ||
875 | register is asserted the USBN will assert an | ||
876 | interrupt. */ | ||
877 | uint64_t u2n_d_pf : 1; /**< When set (1) and bit 29 of the USBN_INT_SUM | ||
878 | register is asserted the USBN will assert an | ||
879 | interrupt. */ | ||
880 | uint64_t u2n_d_pe : 1; /**< When set (1) and bit 28 of the USBN_INT_SUM | ||
881 | register is asserted the USBN will assert an | ||
882 | interrupt. */ | ||
883 | uint64_t n2u_pe : 1; /**< When set (1) and bit 27 of the USBN_INT_SUM | ||
884 | register is asserted the USBN will assert an | ||
885 | interrupt. */ | ||
886 | uint64_t n2u_pf : 1; /**< When set (1) and bit 26 of the USBN_INT_SUM | ||
887 | register is asserted the USBN will assert an | ||
888 | interrupt. */ | ||
889 | uint64_t uod_pf : 1; /**< When set (1) and bit 25 of the USBN_INT_SUM | ||
890 | register is asserted the USBN will assert an | ||
891 | interrupt. */ | ||
892 | uint64_t uod_pe : 1; /**< When set (1) and bit 24 of the USBN_INT_SUM | ||
893 | register is asserted the USBN will assert an | ||
894 | interrupt. */ | ||
895 | uint64_t rq_q3_e : 1; /**< When set (1) and bit 23 of the USBN_INT_SUM | ||
896 | register is asserted the USBN will assert an | ||
897 | interrupt. */ | ||
898 | uint64_t rq_q3_f : 1; /**< When set (1) and bit 22 of the USBN_INT_SUM | ||
899 | register is asserted the USBN will assert an | ||
900 | interrupt. */ | ||
901 | uint64_t rq_q2_e : 1; /**< When set (1) and bit 21 of the USBN_INT_SUM | ||
902 | register is asserted the USBN will assert an | ||
903 | interrupt. */ | ||
904 | uint64_t rq_q2_f : 1; /**< When set (1) and bit 20 of the USBN_INT_SUM | ||
905 | register is asserted the USBN will assert an | ||
906 | interrupt. */ | ||
907 | uint64_t rg_fi_f : 1; /**< When set (1) and bit 19 of the USBN_INT_SUM | ||
908 | register is asserted the USBN will assert an | ||
909 | interrupt. */ | ||
910 | uint64_t rg_fi_e : 1; /**< When set (1) and bit 18 of the USBN_INT_SUM | ||
911 | register is asserted the USBN will assert an | ||
912 | interrupt. */ | ||
913 | uint64_t l2_fi_f : 1; /**< When set (1) and bit 17 of the USBN_INT_SUM | ||
914 | register is asserted the USBN will assert an | ||
915 | interrupt. */ | ||
916 | uint64_t l2_fi_e : 1; /**< When set (1) and bit 16 of the USBN_INT_SUM | ||
917 | register is asserted the USBN will assert an | ||
918 | interrupt. */ | ||
919 | uint64_t l2c_a_f : 1; /**< When set (1) and bit 15 of the USBN_INT_SUM | ||
920 | register is asserted the USBN will assert an | ||
921 | interrupt. */ | ||
922 | uint64_t l2c_s_e : 1; /**< When set (1) and bit 14 of the USBN_INT_SUM | ||
923 | register is asserted the USBN will assert an | ||
924 | interrupt. */ | ||
925 | uint64_t dcred_f : 1; /**< When set (1) and bit 13 of the USBN_INT_SUM | ||
926 | register is asserted the USBN will assert an | ||
927 | interrupt. */ | ||
928 | uint64_t dcred_e : 1; /**< When set (1) and bit 12 of the USBN_INT_SUM | ||
929 | register is asserted the USBN will assert an | ||
930 | interrupt. */ | ||
931 | uint64_t lt_pu_f : 1; /**< When set (1) and bit 11 of the USBN_INT_SUM | ||
932 | register is asserted the USBN will assert an | ||
933 | interrupt. */ | ||
934 | uint64_t lt_po_e : 1; /**< When set (1) and bit 10 of the USBN_INT_SUM | ||
935 | register is asserted the USBN will assert an | ||
936 | interrupt. */ | ||
937 | uint64_t nt_pu_f : 1; /**< When set (1) and bit 9 of the USBN_INT_SUM | ||
938 | register is asserted the USBN will assert an | ||
939 | interrupt. */ | ||
940 | uint64_t nt_po_e : 1; /**< When set (1) and bit 8 of the USBN_INT_SUM | ||
941 | register is asserted the USBN will assert an | ||
942 | interrupt. */ | ||
943 | uint64_t pt_pu_f : 1; /**< When set (1) and bit 7 of the USBN_INT_SUM | ||
944 | register is asserted the USBN will assert an | ||
945 | interrupt. */ | ||
946 | uint64_t pt_po_e : 1; /**< When set (1) and bit 6 of the USBN_INT_SUM | ||
947 | register is asserted the USBN will assert an | ||
948 | interrupt. */ | ||
949 | uint64_t lr_pu_f : 1; /**< When set (1) and bit 5 of the USBN_INT_SUM | ||
950 | register is asserted the USBN will assert an | ||
951 | interrupt. */ | ||
952 | uint64_t lr_po_e : 1; /**< When set (1) and bit 4 of the USBN_INT_SUM | ||
953 | register is asserted the USBN will assert an | ||
954 | interrupt. */ | ||
955 | uint64_t nr_pu_f : 1; /**< When set (1) and bit 3 of the USBN_INT_SUM | ||
956 | register is asserted the USBN will assert an | ||
957 | interrupt. */ | ||
958 | uint64_t nr_po_e : 1; /**< When set (1) and bit 2 of the USBN_INT_SUM | ||
959 | register is asserted the USBN will assert an | ||
960 | interrupt. */ | ||
961 | uint64_t pr_pu_f : 1; /**< When set (1) and bit 1 of the USBN_INT_SUM | ||
962 | register is asserted the USBN will assert an | ||
963 | interrupt. */ | ||
964 | uint64_t pr_po_e : 1; /**< When set (1) and bit 0 of the USBN_INT_SUM | ||
965 | register is asserted the USBN will assert an | ||
966 | interrupt. */ | ||
967 | } s; | ||
968 | struct cvmx_usbnx_int_enb_s cn30xx; | ||
969 | struct cvmx_usbnx_int_enb_s cn31xx; | ||
970 | struct cvmx_usbnx_int_enb_cn50xx | ||
971 | { | ||
972 | uint64_t reserved_38_63 : 26; | ||
973 | uint64_t nd4o_dpf : 1; /**< When set (1) and bit 37 of the USBN_INT_SUM | ||
974 | register is asserted the USBN will assert an | ||
975 | interrupt. */ | ||
976 | uint64_t nd4o_dpe : 1; /**< When set (1) and bit 36 of the USBN_INT_SUM | ||
977 | register is asserted the USBN will assert an | ||
978 | interrupt. */ | ||
979 | uint64_t nd4o_rpf : 1; /**< When set (1) and bit 35 of the USBN_INT_SUM | ||
980 | register is asserted the USBN will assert an | ||
981 | interrupt. */ | ||
982 | uint64_t nd4o_rpe : 1; /**< When set (1) and bit 34 of the USBN_INT_SUM | ||
983 | register is asserted the USBN will assert an | ||
984 | interrupt. */ | ||
985 | uint64_t ltl_f_pf : 1; /**< When set (1) and bit 33 of the USBN_INT_SUM | ||
986 | register is asserted the USBN will assert an | ||
987 | interrupt. */ | ||
988 | uint64_t ltl_f_pe : 1; /**< When set (1) and bit 32 of the USBN_INT_SUM | ||
989 | register is asserted the USBN will assert an | ||
990 | interrupt. */ | ||
991 | uint64_t reserved_26_31 : 6; | ||
992 | uint64_t uod_pf : 1; /**< When set (1) and bit 25 of the USBN_INT_SUM | ||
993 | register is asserted the USBN will assert an | ||
994 | interrupt. */ | ||
995 | uint64_t uod_pe : 1; /**< When set (1) and bit 24 of the USBN_INT_SUM | ||
996 | register is asserted the USBN will assert an | ||
997 | interrupt. */ | ||
998 | uint64_t rq_q3_e : 1; /**< When set (1) and bit 23 of the USBN_INT_SUM | ||
999 | register is asserted the USBN will assert an | ||
1000 | interrupt. */ | ||
1001 | uint64_t rq_q3_f : 1; /**< When set (1) and bit 22 of the USBN_INT_SUM | ||
1002 | register is asserted the USBN will assert an | ||
1003 | interrupt. */ | ||
1004 | uint64_t rq_q2_e : 1; /**< When set (1) and bit 21 of the USBN_INT_SUM | ||
1005 | register is asserted the USBN will assert an | ||
1006 | interrupt. */ | ||
1007 | uint64_t rq_q2_f : 1; /**< When set (1) and bit 20 of the USBN_INT_SUM | ||
1008 | register is asserted the USBN will assert an | ||
1009 | interrupt. */ | ||
1010 | uint64_t rg_fi_f : 1; /**< When set (1) and bit 19 of the USBN_INT_SUM | ||
1011 | register is asserted the USBN will assert an | ||
1012 | interrupt. */ | ||
1013 | uint64_t rg_fi_e : 1; /**< When set (1) and bit 18 of the USBN_INT_SUM | ||
1014 | register is asserted the USBN will assert an | ||
1015 | interrupt. */ | ||
1016 | uint64_t l2_fi_f : 1; /**< When set (1) and bit 17 of the USBN_INT_SUM | ||
1017 | register is asserted the USBN will assert an | ||
1018 | interrupt. */ | ||
1019 | uint64_t l2_fi_e : 1; /**< When set (1) and bit 16 of the USBN_INT_SUM | ||
1020 | register is asserted the USBN will assert an | ||
1021 | interrupt. */ | ||
1022 | uint64_t l2c_a_f : 1; /**< When set (1) and bit 15 of the USBN_INT_SUM | ||
1023 | register is asserted the USBN will assert an | ||
1024 | interrupt. */ | ||
1025 | uint64_t l2c_s_e : 1; /**< When set (1) and bit 14 of the USBN_INT_SUM | ||
1026 | register is asserted the USBN will assert an | ||
1027 | interrupt. */ | ||
1028 | uint64_t dcred_f : 1; /**< When set (1) and bit 13 of the USBN_INT_SUM | ||
1029 | register is asserted the USBN will assert an | ||
1030 | interrupt. */ | ||
1031 | uint64_t dcred_e : 1; /**< When set (1) and bit 12 of the USBN_INT_SUM | ||
1032 | register is asserted the USBN will assert an | ||
1033 | interrupt. */ | ||
1034 | uint64_t lt_pu_f : 1; /**< When set (1) and bit 11 of the USBN_INT_SUM | ||
1035 | register is asserted the USBN will assert an | ||
1036 | interrupt. */ | ||
1037 | uint64_t lt_po_e : 1; /**< When set (1) and bit 10 of the USBN_INT_SUM | ||
1038 | register is asserted the USBN will assert an | ||
1039 | interrupt. */ | ||
1040 | uint64_t nt_pu_f : 1; /**< When set (1) and bit 9 of the USBN_INT_SUM | ||
1041 | register is asserted the USBN will assert an | ||
1042 | interrupt. */ | ||
1043 | uint64_t nt_po_e : 1; /**< When set (1) and bit 8 of the USBN_INT_SUM | ||
1044 | register is asserted the USBN will assert an | ||
1045 | interrupt. */ | ||
1046 | uint64_t pt_pu_f : 1; /**< When set (1) and bit 7 of the USBN_INT_SUM | ||
1047 | register is asserted the USBN will assert an | ||
1048 | interrupt. */ | ||
1049 | uint64_t pt_po_e : 1; /**< When set (1) and bit 6 of the USBN_INT_SUM | ||
1050 | register is asserted the USBN will assert an | ||
1051 | interrupt. */ | ||
1052 | uint64_t lr_pu_f : 1; /**< When set (1) and bit 5 of the USBN_INT_SUM | ||
1053 | register is asserted the USBN will assert an | ||
1054 | interrupt. */ | ||
1055 | uint64_t lr_po_e : 1; /**< When set (1) and bit 4 of the USBN_INT_SUM | ||
1056 | register is asserted the USBN will assert an | ||
1057 | interrupt. */ | ||
1058 | uint64_t nr_pu_f : 1; /**< When set (1) and bit 3 of the USBN_INT_SUM | ||
1059 | register is asserted the USBN will assert an | ||
1060 | interrupt. */ | ||
1061 | uint64_t nr_po_e : 1; /**< When set (1) and bit 2 of the USBN_INT_SUM | ||
1062 | register is asserted the USBN will assert an | ||
1063 | interrupt. */ | ||
1064 | uint64_t pr_pu_f : 1; /**< When set (1) and bit 1 of the USBN_INT_SUM | ||
1065 | register is asserted the USBN will assert an | ||
1066 | interrupt. */ | ||
1067 | uint64_t pr_po_e : 1; /**< When set (1) and bit 0 of the USBN_INT_SUM | ||
1068 | register is asserted the USBN will assert an | ||
1069 | interrupt. */ | ||
1070 | } cn50xx; | ||
1071 | struct cvmx_usbnx_int_enb_cn50xx cn52xx; | ||
1072 | struct cvmx_usbnx_int_enb_cn50xx cn52xxp1; | ||
1073 | struct cvmx_usbnx_int_enb_cn50xx cn56xx; | ||
1074 | struct cvmx_usbnx_int_enb_cn50xx cn56xxp1; | ||
1075 | }; | ||
1076 | typedef union cvmx_usbnx_int_enb cvmx_usbnx_int_enb_t; | ||
1077 | |||
1078 | /** | ||
1079 | * cvmx_usbn#_int_sum | ||
1080 | * | ||
1081 | * USBN_INT_SUM = USBN's Interrupt Summary Register | ||
1082 | * | ||
1083 | * Contains the diffrent interrupt summary bits of the USBN. | ||
1084 | */ | ||
1085 | union cvmx_usbnx_int_sum | ||
1086 | { | ||
1087 | uint64_t u64; | ||
1088 | struct cvmx_usbnx_int_sum_s | ||
1089 | { | ||
1090 | uint64_t reserved_38_63 : 26; | ||
1091 | uint64_t nd4o_dpf : 1; /**< NCB DMA Out Data Fifo Push Full. */ | ||
1092 | uint64_t nd4o_dpe : 1; /**< NCB DMA Out Data Fifo Pop Empty. */ | ||
1093 | uint64_t nd4o_rpf : 1; /**< NCB DMA Out Request Fifo Push Full. */ | ||
1094 | uint64_t nd4o_rpe : 1; /**< NCB DMA Out Request Fifo Pop Empty. */ | ||
1095 | uint64_t ltl_f_pf : 1; /**< L2C Transfer Length Fifo Push Full. */ | ||
1096 | uint64_t ltl_f_pe : 1; /**< L2C Transfer Length Fifo Pop Empty. */ | ||
1097 | uint64_t u2n_c_pe : 1; /**< U2N Control Fifo Pop Empty. */ | ||
1098 | uint64_t u2n_c_pf : 1; /**< U2N Control Fifo Push Full. */ | ||
1099 | uint64_t u2n_d_pf : 1; /**< U2N Data Fifo Push Full. */ | ||
1100 | uint64_t u2n_d_pe : 1; /**< U2N Data Fifo Pop Empty. */ | ||
1101 | uint64_t n2u_pe : 1; /**< N2U Fifo Pop Empty. */ | ||
1102 | uint64_t n2u_pf : 1; /**< N2U Fifo Push Full. */ | ||
1103 | uint64_t uod_pf : 1; /**< UOD Fifo Push Full. */ | ||
1104 | uint64_t uod_pe : 1; /**< UOD Fifo Pop Empty. */ | ||
1105 | uint64_t rq_q3_e : 1; /**< Request Queue-3 Fifo Pushed When Full. */ | ||
1106 | uint64_t rq_q3_f : 1; /**< Request Queue-3 Fifo Pushed When Full. */ | ||
1107 | uint64_t rq_q2_e : 1; /**< Request Queue-2 Fifo Pushed When Full. */ | ||
1108 | uint64_t rq_q2_f : 1; /**< Request Queue-2 Fifo Pushed When Full. */ | ||
1109 | uint64_t rg_fi_f : 1; /**< Register Request Fifo Pushed When Full. */ | ||
1110 | uint64_t rg_fi_e : 1; /**< Register Request Fifo Pushed When Full. */ | ||
1111 | uint64_t lt_fi_f : 1; /**< L2C Request Fifo Pushed When Full. */ | ||
1112 | uint64_t lt_fi_e : 1; /**< L2C Request Fifo Pushed When Full. */ | ||
1113 | uint64_t l2c_a_f : 1; /**< L2C Credit Count Added When Full. */ | ||
1114 | uint64_t l2c_s_e : 1; /**< L2C Credit Count Subtracted When Empty. */ | ||
1115 | uint64_t dcred_f : 1; /**< Data CreditFifo Pushed When Full. */ | ||
1116 | uint64_t dcred_e : 1; /**< Data Credit Fifo Pushed When Full. */ | ||
1117 | uint64_t lt_pu_f : 1; /**< L2C Trasaction Fifo Pushed When Full. */ | ||
1118 | uint64_t lt_po_e : 1; /**< L2C Trasaction Fifo Popped When Full. */ | ||
1119 | uint64_t nt_pu_f : 1; /**< NPI Trasaction Fifo Pushed When Full. */ | ||
1120 | uint64_t nt_po_e : 1; /**< NPI Trasaction Fifo Popped When Full. */ | ||
1121 | uint64_t pt_pu_f : 1; /**< PP Trasaction Fifo Pushed When Full. */ | ||
1122 | uint64_t pt_po_e : 1; /**< PP Trasaction Fifo Popped When Full. */ | ||
1123 | uint64_t lr_pu_f : 1; /**< L2C Request Fifo Pushed When Full. */ | ||
1124 | uint64_t lr_po_e : 1; /**< L2C Request Fifo Popped When Empty. */ | ||
1125 | uint64_t nr_pu_f : 1; /**< NPI Request Fifo Pushed When Full. */ | ||
1126 | uint64_t nr_po_e : 1; /**< NPI Request Fifo Popped When Empty. */ | ||
1127 | uint64_t pr_pu_f : 1; /**< PP Request Fifo Pushed When Full. */ | ||
1128 | uint64_t pr_po_e : 1; /**< PP Request Fifo Popped When Empty. */ | ||
1129 | } s; | ||
1130 | struct cvmx_usbnx_int_sum_s cn30xx; | ||
1131 | struct cvmx_usbnx_int_sum_s cn31xx; | ||
1132 | struct cvmx_usbnx_int_sum_cn50xx | ||
1133 | { | ||
1134 | uint64_t reserved_38_63 : 26; | ||
1135 | uint64_t nd4o_dpf : 1; /**< NCB DMA Out Data Fifo Push Full. */ | ||
1136 | uint64_t nd4o_dpe : 1; /**< NCB DMA Out Data Fifo Pop Empty. */ | ||
1137 | uint64_t nd4o_rpf : 1; /**< NCB DMA Out Request Fifo Push Full. */ | ||
1138 | uint64_t nd4o_rpe : 1; /**< NCB DMA Out Request Fifo Pop Empty. */ | ||
1139 | uint64_t ltl_f_pf : 1; /**< L2C Transfer Length Fifo Push Full. */ | ||
1140 | uint64_t ltl_f_pe : 1; /**< L2C Transfer Length Fifo Pop Empty. */ | ||
1141 | uint64_t reserved_26_31 : 6; | ||
1142 | uint64_t uod_pf : 1; /**< UOD Fifo Push Full. */ | ||
1143 | uint64_t uod_pe : 1; /**< UOD Fifo Pop Empty. */ | ||
1144 | uint64_t rq_q3_e : 1; /**< Request Queue-3 Fifo Pushed When Full. */ | ||
1145 | uint64_t rq_q3_f : 1; /**< Request Queue-3 Fifo Pushed When Full. */ | ||
1146 | uint64_t rq_q2_e : 1; /**< Request Queue-2 Fifo Pushed When Full. */ | ||
1147 | uint64_t rq_q2_f : 1; /**< Request Queue-2 Fifo Pushed When Full. */ | ||
1148 | uint64_t rg_fi_f : 1; /**< Register Request Fifo Pushed When Full. */ | ||
1149 | uint64_t rg_fi_e : 1; /**< Register Request Fifo Pushed When Full. */ | ||
1150 | uint64_t lt_fi_f : 1; /**< L2C Request Fifo Pushed When Full. */ | ||
1151 | uint64_t lt_fi_e : 1; /**< L2C Request Fifo Pushed When Full. */ | ||
1152 | uint64_t l2c_a_f : 1; /**< L2C Credit Count Added When Full. */ | ||
1153 | uint64_t l2c_s_e : 1; /**< L2C Credit Count Subtracted When Empty. */ | ||
1154 | uint64_t dcred_f : 1; /**< Data CreditFifo Pushed When Full. */ | ||
1155 | uint64_t dcred_e : 1; /**< Data Credit Fifo Pushed When Full. */ | ||
1156 | uint64_t lt_pu_f : 1; /**< L2C Trasaction Fifo Pushed When Full. */ | ||
1157 | uint64_t lt_po_e : 1; /**< L2C Trasaction Fifo Popped When Full. */ | ||
1158 | uint64_t nt_pu_f : 1; /**< NPI Trasaction Fifo Pushed When Full. */ | ||
1159 | uint64_t nt_po_e : 1; /**< NPI Trasaction Fifo Popped When Full. */ | ||
1160 | uint64_t pt_pu_f : 1; /**< PP Trasaction Fifo Pushed When Full. */ | ||
1161 | uint64_t pt_po_e : 1; /**< PP Trasaction Fifo Popped When Full. */ | ||
1162 | uint64_t lr_pu_f : 1; /**< L2C Request Fifo Pushed When Full. */ | ||
1163 | uint64_t lr_po_e : 1; /**< L2C Request Fifo Popped When Empty. */ | ||
1164 | uint64_t nr_pu_f : 1; /**< NPI Request Fifo Pushed When Full. */ | ||
1165 | uint64_t nr_po_e : 1; /**< NPI Request Fifo Popped When Empty. */ | ||
1166 | uint64_t pr_pu_f : 1; /**< PP Request Fifo Pushed When Full. */ | ||
1167 | uint64_t pr_po_e : 1; /**< PP Request Fifo Popped When Empty. */ | ||
1168 | } cn50xx; | ||
1169 | struct cvmx_usbnx_int_sum_cn50xx cn52xx; | ||
1170 | struct cvmx_usbnx_int_sum_cn50xx cn52xxp1; | ||
1171 | struct cvmx_usbnx_int_sum_cn50xx cn56xx; | ||
1172 | struct cvmx_usbnx_int_sum_cn50xx cn56xxp1; | ||
1173 | }; | ||
1174 | typedef union cvmx_usbnx_int_sum cvmx_usbnx_int_sum_t; | ||
1175 | |||
1176 | /** | ||
1177 | * cvmx_usbn#_usbp_ctl_status | ||
1178 | * | ||
1179 | * USBN_USBP_CTL_STATUS = USBP Control And Status Register | ||
1180 | * | ||
1181 | * Contains general control and status information for the USBN block. | ||
1182 | */ | ||
1183 | union cvmx_usbnx_usbp_ctl_status | ||
1184 | { | ||
1185 | uint64_t u64; | ||
1186 | struct cvmx_usbnx_usbp_ctl_status_s | ||
1187 | { | ||
1188 | uint64_t txrisetune : 1; /**< HS Transmitter Rise/Fall Time Adjustment */ | ||
1189 | uint64_t txvreftune : 4; /**< HS DC Voltage Level Adjustment */ | ||
1190 | uint64_t txfslstune : 4; /**< FS/LS Source Impedence Adjustment */ | ||
1191 | uint64_t txhsxvtune : 2; /**< Transmitter High-Speed Crossover Adjustment */ | ||
1192 | uint64_t sqrxtune : 3; /**< Squelch Threshold Adjustment */ | ||
1193 | uint64_t compdistune : 3; /**< Disconnect Threshold Adjustment */ | ||
1194 | uint64_t otgtune : 3; /**< VBUS Valid Threshold Adjustment */ | ||
1195 | uint64_t otgdisable : 1; /**< OTG Block Disable */ | ||
1196 | uint64_t portreset : 1; /**< Per_Port Reset */ | ||
1197 | uint64_t drvvbus : 1; /**< Drive VBUS */ | ||
1198 | uint64_t lsbist : 1; /**< Low-Speed BIST Enable. */ | ||
1199 | uint64_t fsbist : 1; /**< Full-Speed BIST Enable. */ | ||
1200 | uint64_t hsbist : 1; /**< High-Speed BIST Enable. */ | ||
1201 | uint64_t bist_done : 1; /**< PHY Bist Done. | ||
1202 | Asserted at the end of the PHY BIST sequence. */ | ||
1203 | uint64_t bist_err : 1; /**< PHY Bist Error. | ||
1204 | Indicates an internal error was detected during | ||
1205 | the BIST sequence. */ | ||
1206 | uint64_t tdata_out : 4; /**< PHY Test Data Out. | ||
1207 | Presents either internaly generated signals or | ||
1208 | test register contents, based upon the value of | ||
1209 | test_data_out_sel. */ | ||
1210 | uint64_t siddq : 1; /**< Drives the USBP (USB-PHY) SIDDQ input. | ||
1211 | Normally should be set to zero. | ||
1212 | When customers have no intent to use USB PHY | ||
1213 | interface, they should: | ||
1214 | - still provide 3.3V to USB_VDD33, and | ||
1215 | - tie USB_REXT to 3.3V supply, and | ||
1216 | - set USBN*_USBP_CTL_STATUS[SIDDQ]=1 */ | ||
1217 | uint64_t txpreemphasistune : 1; /**< HS Transmitter Pre-Emphasis Enable */ | ||
1218 | uint64_t dma_bmode : 1; /**< When set to 1 the L2C DMA address will be updated | ||
1219 | with byte-counts between packets. When set to 0 | ||
1220 | the L2C DMA address is incremented to the next | ||
1221 | 4-byte aligned address after adding byte-count. */ | ||
1222 | uint64_t usbc_end : 1; /**< Bigendian input to the USB Core. This should be | ||
1223 | set to '0' for operation. */ | ||
1224 | uint64_t usbp_bist : 1; /**< PHY, This is cleared '0' to run BIST on the USBP. */ | ||
1225 | uint64_t tclk : 1; /**< PHY Test Clock, used to load TDATA_IN to the USBP. */ | ||
1226 | uint64_t dp_pulld : 1; /**< PHY DP_PULLDOWN input to the USB-PHY. | ||
1227 | This signal enables the pull-down resistance on | ||
1228 | the D+ line. '1' pull down-resistance is connected | ||
1229 | to D+/ '0' pull down resistance is not connected | ||
1230 | to D+. When an A/B device is acting as a host | ||
1231 | (downstream-facing port), dp_pulldown and | ||
1232 | dm_pulldown are enabled. This must not toggle | ||
1233 | during normal opeartion. */ | ||
1234 | uint64_t dm_pulld : 1; /**< PHY DM_PULLDOWN input to the USB-PHY. | ||
1235 | This signal enables the pull-down resistance on | ||
1236 | the D- line. '1' pull down-resistance is connected | ||
1237 | to D-. '0' pull down resistance is not connected | ||
1238 | to D-. When an A/B device is acting as a host | ||
1239 | (downstream-facing port), dp_pulldown and | ||
1240 | dm_pulldown are enabled. This must not toggle | ||
1241 | during normal opeartion. */ | ||
1242 | uint64_t hst_mode : 1; /**< When '0' the USB is acting as HOST, when '1' | ||
1243 | USB is acting as device. This field needs to be | ||
1244 | set while the USB is in reset. */ | ||
1245 | uint64_t tuning : 4; /**< Transmitter Tuning for High-Speed Operation. | ||
1246 | Tunes the current supply and rise/fall output | ||
1247 | times for high-speed operation. | ||
1248 | [20:19] == 11: Current supply increased | ||
1249 | approximately 9% | ||
1250 | [20:19] == 10: Current supply increased | ||
1251 | approximately 4.5% | ||
1252 | [20:19] == 01: Design default. | ||
1253 | [20:19] == 00: Current supply decreased | ||
1254 | approximately 4.5% | ||
1255 | [22:21] == 11: Rise and fall times are increased. | ||
1256 | [22:21] == 10: Design default. | ||
1257 | [22:21] == 01: Rise and fall times are decreased. | ||
1258 | [22:21] == 00: Rise and fall times are decreased | ||
1259 | further as compared to the 01 setting. */ | ||
1260 | uint64_t tx_bs_enh : 1; /**< Transmit Bit Stuffing on [15:8]. | ||
1261 | Enables or disables bit stuffing on data[15:8] | ||
1262 | when bit-stuffing is enabled. */ | ||
1263 | uint64_t tx_bs_en : 1; /**< Transmit Bit Stuffing on [7:0]. | ||
1264 | Enables or disables bit stuffing on data[7:0] | ||
1265 | when bit-stuffing is enabled. */ | ||
1266 | uint64_t loop_enb : 1; /**< PHY Loopback Test Enable. | ||
1267 | '1': During data transmission the receive is | ||
1268 | enabled. | ||
1269 | '0': During data transmission the receive is | ||
1270 | disabled. | ||
1271 | Must be '0' for normal operation. */ | ||
1272 | uint64_t vtest_enb : 1; /**< Analog Test Pin Enable. | ||
1273 | '1' The PHY's analog_test pin is enabled for the | ||
1274 | input and output of applicable analog test signals. | ||
1275 | '0' THe analog_test pin is disabled. */ | ||
1276 | uint64_t bist_enb : 1; /**< Built-In Self Test Enable. | ||
1277 | Used to activate BIST in the PHY. */ | ||
1278 | uint64_t tdata_sel : 1; /**< Test Data Out Select. | ||
1279 | '1' test_data_out[3:0] (PHY) register contents | ||
1280 | are output. '0' internaly generated signals are | ||
1281 | output. */ | ||
1282 | uint64_t taddr_in : 4; /**< Mode Address for Test Interface. | ||
1283 | Specifies the register address for writing to or | ||
1284 | reading from the PHY test interface register. */ | ||
1285 | uint64_t tdata_in : 8; /**< Internal Testing Register Input Data and Select | ||
1286 | This is a test bus. Data is present on [3:0], | ||
1287 | and its corresponding select (enable) is present | ||
1288 | on bits [7:4]. */ | ||
1289 | uint64_t ate_reset : 1; /**< Reset input from automatic test equipment. | ||
1290 | This is a test signal. When the USB Core is | ||
1291 | powered up (not in Susned Mode), an automatic | ||
1292 | tester can use this to disable phy_clock and | ||
1293 | free_clk, then re-eanable them with an aligned | ||
1294 | phase. | ||
1295 | '1': The phy_clk and free_clk outputs are | ||
1296 | disabled. "0": The phy_clock and free_clk outputs | ||
1297 | are available within a specific period after the | ||
1298 | de-assertion. */ | ||
1299 | } s; | ||
1300 | struct cvmx_usbnx_usbp_ctl_status_cn30xx | ||
1301 | { | ||
1302 | uint64_t reserved_38_63 : 26; | ||
1303 | uint64_t bist_done : 1; /**< PHY Bist Done. | ||
1304 | Asserted at the end of the PHY BIST sequence. */ | ||
1305 | uint64_t bist_err : 1; /**< PHY Bist Error. | ||
1306 | Indicates an internal error was detected during | ||
1307 | the BIST sequence. */ | ||
1308 | uint64_t tdata_out : 4; /**< PHY Test Data Out. | ||
1309 | Presents either internaly generated signals or | ||
1310 | test register contents, based upon the value of | ||
1311 | test_data_out_sel. */ | ||
1312 | uint64_t reserved_30_31 : 2; | ||
1313 | uint64_t dma_bmode : 1; /**< When set to 1 the L2C DMA address will be updated | ||
1314 | with byte-counts between packets. When set to 0 | ||
1315 | the L2C DMA address is incremented to the next | ||
1316 | 4-byte aligned address after adding byte-count. */ | ||
1317 | uint64_t usbc_end : 1; /**< Bigendian input to the USB Core. This should be | ||
1318 | set to '0' for operation. */ | ||
1319 | uint64_t usbp_bist : 1; /**< PHY, This is cleared '0' to run BIST on the USBP. */ | ||
1320 | uint64_t tclk : 1; /**< PHY Test Clock, used to load TDATA_IN to the USBP. */ | ||
1321 | uint64_t dp_pulld : 1; /**< PHY DP_PULLDOWN input to the USB-PHY. | ||
1322 | This signal enables the pull-down resistance on | ||
1323 | the D+ line. '1' pull down-resistance is connected | ||
1324 | to D+/ '0' pull down resistance is not connected | ||
1325 | to D+. When an A/B device is acting as a host | ||
1326 | (downstream-facing port), dp_pulldown and | ||
1327 | dm_pulldown are enabled. This must not toggle | ||
1328 | during normal opeartion. */ | ||
1329 | uint64_t dm_pulld : 1; /**< PHY DM_PULLDOWN input to the USB-PHY. | ||
1330 | This signal enables the pull-down resistance on | ||
1331 | the D- line. '1' pull down-resistance is connected | ||
1332 | to D-. '0' pull down resistance is not connected | ||
1333 | to D-. When an A/B device is acting as a host | ||
1334 | (downstream-facing port), dp_pulldown and | ||
1335 | dm_pulldown are enabled. This must not toggle | ||
1336 | during normal opeartion. */ | ||
1337 | uint64_t hst_mode : 1; /**< When '0' the USB is acting as HOST, when '1' | ||
1338 | USB is acting as device. This field needs to be | ||
1339 | set while the USB is in reset. */ | ||
1340 | uint64_t tuning : 4; /**< Transmitter Tuning for High-Speed Operation. | ||
1341 | Tunes the current supply and rise/fall output | ||
1342 | times for high-speed operation. | ||
1343 | [20:19] == 11: Current supply increased | ||
1344 | approximately 9% | ||
1345 | [20:19] == 10: Current supply increased | ||
1346 | approximately 4.5% | ||
1347 | [20:19] == 01: Design default. | ||
1348 | [20:19] == 00: Current supply decreased | ||
1349 | approximately 4.5% | ||
1350 | [22:21] == 11: Rise and fall times are increased. | ||
1351 | [22:21] == 10: Design default. | ||
1352 | [22:21] == 01: Rise and fall times are decreased. | ||
1353 | [22:21] == 00: Rise and fall times are decreased | ||
1354 | further as compared to the 01 setting. */ | ||
1355 | uint64_t tx_bs_enh : 1; /**< Transmit Bit Stuffing on [15:8]. | ||
1356 | Enables or disables bit stuffing on data[15:8] | ||
1357 | when bit-stuffing is enabled. */ | ||
1358 | uint64_t tx_bs_en : 1; /**< Transmit Bit Stuffing on [7:0]. | ||
1359 | Enables or disables bit stuffing on data[7:0] | ||
1360 | when bit-stuffing is enabled. */ | ||
1361 | uint64_t loop_enb : 1; /**< PHY Loopback Test Enable. | ||
1362 | '1': During data transmission the receive is | ||
1363 | enabled. | ||
1364 | '0': During data transmission the receive is | ||
1365 | disabled. | ||
1366 | Must be '0' for normal operation. */ | ||
1367 | uint64_t vtest_enb : 1; /**< Analog Test Pin Enable. | ||
1368 | '1' The PHY's analog_test pin is enabled for the | ||
1369 | input and output of applicable analog test signals. | ||
1370 | '0' THe analog_test pin is disabled. */ | ||
1371 | uint64_t bist_enb : 1; /**< Built-In Self Test Enable. | ||
1372 | Used to activate BIST in the PHY. */ | ||
1373 | uint64_t tdata_sel : 1; /**< Test Data Out Select. | ||
1374 | '1' test_data_out[3:0] (PHY) register contents | ||
1375 | are output. '0' internaly generated signals are | ||
1376 | output. */ | ||
1377 | uint64_t taddr_in : 4; /**< Mode Address for Test Interface. | ||
1378 | Specifies the register address for writing to or | ||
1379 | reading from the PHY test interface register. */ | ||
1380 | uint64_t tdata_in : 8; /**< Internal Testing Register Input Data and Select | ||
1381 | This is a test bus. Data is present on [3:0], | ||
1382 | and its corresponding select (enable) is present | ||
1383 | on bits [7:4]. */ | ||
1384 | uint64_t ate_reset : 1; /**< Reset input from automatic test equipment. | ||
1385 | This is a test signal. When the USB Core is | ||
1386 | powered up (not in Susned Mode), an automatic | ||
1387 | tester can use this to disable phy_clock and | ||
1388 | free_clk, then re-eanable them with an aligned | ||
1389 | phase. | ||
1390 | '1': The phy_clk and free_clk outputs are | ||
1391 | disabled. "0": The phy_clock and free_clk outputs | ||
1392 | are available within a specific period after the | ||
1393 | de-assertion. */ | ||
1394 | } cn30xx; | ||
1395 | struct cvmx_usbnx_usbp_ctl_status_cn30xx cn31xx; | ||
1396 | struct cvmx_usbnx_usbp_ctl_status_cn50xx | ||
1397 | { | ||
1398 | uint64_t txrisetune : 1; /**< HS Transmitter Rise/Fall Time Adjustment */ | ||
1399 | uint64_t txvreftune : 4; /**< HS DC Voltage Level Adjustment */ | ||
1400 | uint64_t txfslstune : 4; /**< FS/LS Source Impedence Adjustment */ | ||
1401 | uint64_t txhsxvtune : 2; /**< Transmitter High-Speed Crossover Adjustment */ | ||
1402 | uint64_t sqrxtune : 3; /**< Squelch Threshold Adjustment */ | ||
1403 | uint64_t compdistune : 3; /**< Disconnect Threshold Adjustment */ | ||
1404 | uint64_t otgtune : 3; /**< VBUS Valid Threshold Adjustment */ | ||
1405 | uint64_t otgdisable : 1; /**< OTG Block Disable */ | ||
1406 | uint64_t portreset : 1; /**< Per_Port Reset */ | ||
1407 | uint64_t drvvbus : 1; /**< Drive VBUS */ | ||
1408 | uint64_t lsbist : 1; /**< Low-Speed BIST Enable. */ | ||
1409 | uint64_t fsbist : 1; /**< Full-Speed BIST Enable. */ | ||
1410 | uint64_t hsbist : 1; /**< High-Speed BIST Enable. */ | ||
1411 | uint64_t bist_done : 1; /**< PHY Bist Done. | ||
1412 | Asserted at the end of the PHY BIST sequence. */ | ||
1413 | uint64_t bist_err : 1; /**< PHY Bist Error. | ||
1414 | Indicates an internal error was detected during | ||
1415 | the BIST sequence. */ | ||
1416 | uint64_t tdata_out : 4; /**< PHY Test Data Out. | ||
1417 | Presents either internaly generated signals or | ||
1418 | test register contents, based upon the value of | ||
1419 | test_data_out_sel. */ | ||
1420 | uint64_t reserved_31_31 : 1; | ||
1421 | uint64_t txpreemphasistune : 1; /**< HS Transmitter Pre-Emphasis Enable */ | ||
1422 | uint64_t dma_bmode : 1; /**< When set to 1 the L2C DMA address will be updated | ||
1423 | with byte-counts between packets. When set to 0 | ||
1424 | the L2C DMA address is incremented to the next | ||
1425 | 4-byte aligned address after adding byte-count. */ | ||
1426 | uint64_t usbc_end : 1; /**< Bigendian input to the USB Core. This should be | ||
1427 | set to '0' for operation. */ | ||
1428 | uint64_t usbp_bist : 1; /**< PHY, This is cleared '0' to run BIST on the USBP. */ | ||
1429 | uint64_t tclk : 1; /**< PHY Test Clock, used to load TDATA_IN to the USBP. */ | ||
1430 | uint64_t dp_pulld : 1; /**< PHY DP_PULLDOWN input to the USB-PHY. | ||
1431 | This signal enables the pull-down resistance on | ||
1432 | the D+ line. '1' pull down-resistance is connected | ||
1433 | to D+/ '0' pull down resistance is not connected | ||
1434 | to D+. When an A/B device is acting as a host | ||
1435 | (downstream-facing port), dp_pulldown and | ||
1436 | dm_pulldown are enabled. This must not toggle | ||
1437 | during normal opeartion. */ | ||
1438 | uint64_t dm_pulld : 1; /**< PHY DM_PULLDOWN input to the USB-PHY. | ||
1439 | This signal enables the pull-down resistance on | ||
1440 | the D- line. '1' pull down-resistance is connected | ||
1441 | to D-. '0' pull down resistance is not connected | ||
1442 | to D-. When an A/B device is acting as a host | ||
1443 | (downstream-facing port), dp_pulldown and | ||
1444 | dm_pulldown are enabled. This must not toggle | ||
1445 | during normal opeartion. */ | ||
1446 | uint64_t hst_mode : 1; /**< When '0' the USB is acting as HOST, when '1' | ||
1447 | USB is acting as device. This field needs to be | ||
1448 | set while the USB is in reset. */ | ||
1449 | uint64_t reserved_19_22 : 4; | ||
1450 | uint64_t tx_bs_enh : 1; /**< Transmit Bit Stuffing on [15:8]. | ||
1451 | Enables or disables bit stuffing on data[15:8] | ||
1452 | when bit-stuffing is enabled. */ | ||
1453 | uint64_t tx_bs_en : 1; /**< Transmit Bit Stuffing on [7:0]. | ||
1454 | Enables or disables bit stuffing on data[7:0] | ||
1455 | when bit-stuffing is enabled. */ | ||
1456 | uint64_t loop_enb : 1; /**< PHY Loopback Test Enable. | ||
1457 | '1': During data transmission the receive is | ||
1458 | enabled. | ||
1459 | '0': During data transmission the receive is | ||
1460 | disabled. | ||
1461 | Must be '0' for normal operation. */ | ||
1462 | uint64_t vtest_enb : 1; /**< Analog Test Pin Enable. | ||
1463 | '1' The PHY's analog_test pin is enabled for the | ||
1464 | input and output of applicable analog test signals. | ||
1465 | '0' THe analog_test pin is disabled. */ | ||
1466 | uint64_t bist_enb : 1; /**< Built-In Self Test Enable. | ||
1467 | Used to activate BIST in the PHY. */ | ||
1468 | uint64_t tdata_sel : 1; /**< Test Data Out Select. | ||
1469 | '1' test_data_out[3:0] (PHY) register contents | ||
1470 | are output. '0' internaly generated signals are | ||
1471 | output. */ | ||
1472 | uint64_t taddr_in : 4; /**< Mode Address for Test Interface. | ||
1473 | Specifies the register address for writing to or | ||
1474 | reading from the PHY test interface register. */ | ||
1475 | uint64_t tdata_in : 8; /**< Internal Testing Register Input Data and Select | ||
1476 | This is a test bus. Data is present on [3:0], | ||
1477 | and its corresponding select (enable) is present | ||
1478 | on bits [7:4]. */ | ||
1479 | uint64_t ate_reset : 1; /**< Reset input from automatic test equipment. | ||
1480 | This is a test signal. When the USB Core is | ||
1481 | powered up (not in Susned Mode), an automatic | ||
1482 | tester can use this to disable phy_clock and | ||
1483 | free_clk, then re-eanable them with an aligned | ||
1484 | phase. | ||
1485 | '1': The phy_clk and free_clk outputs are | ||
1486 | disabled. "0": The phy_clock and free_clk outputs | ||
1487 | are available within a specific period after the | ||
1488 | de-assertion. */ | ||
1489 | } cn50xx; | ||
1490 | struct cvmx_usbnx_usbp_ctl_status_cn52xx | ||
1491 | { | ||
1492 | uint64_t txrisetune : 1; /**< HS Transmitter Rise/Fall Time Adjustment */ | ||
1493 | uint64_t txvreftune : 4; /**< HS DC Voltage Level Adjustment */ | ||
1494 | uint64_t txfslstune : 4; /**< FS/LS Source Impedence Adjustment */ | ||
1495 | uint64_t txhsxvtune : 2; /**< Transmitter High-Speed Crossover Adjustment */ | ||
1496 | uint64_t sqrxtune : 3; /**< Squelch Threshold Adjustment */ | ||
1497 | uint64_t compdistune : 3; /**< Disconnect Threshold Adjustment */ | ||
1498 | uint64_t otgtune : 3; /**< VBUS Valid Threshold Adjustment */ | ||
1499 | uint64_t otgdisable : 1; /**< OTG Block Disable */ | ||
1500 | uint64_t portreset : 1; /**< Per_Port Reset */ | ||
1501 | uint64_t drvvbus : 1; /**< Drive VBUS */ | ||
1502 | uint64_t lsbist : 1; /**< Low-Speed BIST Enable. */ | ||
1503 | uint64_t fsbist : 1; /**< Full-Speed BIST Enable. */ | ||
1504 | uint64_t hsbist : 1; /**< High-Speed BIST Enable. */ | ||
1505 | uint64_t bist_done : 1; /**< PHY Bist Done. | ||
1506 | Asserted at the end of the PHY BIST sequence. */ | ||
1507 | uint64_t bist_err : 1; /**< PHY Bist Error. | ||
1508 | Indicates an internal error was detected during | ||
1509 | the BIST sequence. */ | ||
1510 | uint64_t tdata_out : 4; /**< PHY Test Data Out. | ||
1511 | Presents either internaly generated signals or | ||
1512 | test register contents, based upon the value of | ||
1513 | test_data_out_sel. */ | ||
1514 | uint64_t siddq : 1; /**< Drives the USBP (USB-PHY) SIDDQ input. | ||
1515 | Normally should be set to zero. | ||
1516 | When customers have no intent to use USB PHY | ||
1517 | interface, they should: | ||
1518 | - still provide 3.3V to USB_VDD33, and | ||
1519 | - tie USB_REXT to 3.3V supply, and | ||
1520 | - set USBN*_USBP_CTL_STATUS[SIDDQ]=1 */ | ||
1521 | uint64_t txpreemphasistune : 1; /**< HS Transmitter Pre-Emphasis Enable */ | ||
1522 | uint64_t dma_bmode : 1; /**< When set to 1 the L2C DMA address will be updated | ||
1523 | with byte-counts between packets. When set to 0 | ||
1524 | the L2C DMA address is incremented to the next | ||
1525 | 4-byte aligned address after adding byte-count. */ | ||
1526 | uint64_t usbc_end : 1; /**< Bigendian input to the USB Core. This should be | ||
1527 | set to '0' for operation. */ | ||
1528 | uint64_t usbp_bist : 1; /**< PHY, This is cleared '0' to run BIST on the USBP. */ | ||
1529 | uint64_t tclk : 1; /**< PHY Test Clock, used to load TDATA_IN to the USBP. */ | ||
1530 | uint64_t dp_pulld : 1; /**< PHY DP_PULLDOWN input to the USB-PHY. | ||
1531 | This signal enables the pull-down resistance on | ||
1532 | the D+ line. '1' pull down-resistance is connected | ||
1533 | to D+/ '0' pull down resistance is not connected | ||
1534 | to D+. When an A/B device is acting as a host | ||
1535 | (downstream-facing port), dp_pulldown and | ||
1536 | dm_pulldown are enabled. This must not toggle | ||
1537 | during normal opeartion. */ | ||
1538 | uint64_t dm_pulld : 1; /**< PHY DM_PULLDOWN input to the USB-PHY. | ||
1539 | This signal enables the pull-down resistance on | ||
1540 | the D- line. '1' pull down-resistance is connected | ||
1541 | to D-. '0' pull down resistance is not connected | ||
1542 | to D-. When an A/B device is acting as a host | ||
1543 | (downstream-facing port), dp_pulldown and | ||
1544 | dm_pulldown are enabled. This must not toggle | ||
1545 | during normal opeartion. */ | ||
1546 | uint64_t hst_mode : 1; /**< When '0' the USB is acting as HOST, when '1' | ||
1547 | USB is acting as device. This field needs to be | ||
1548 | set while the USB is in reset. */ | ||
1549 | uint64_t reserved_19_22 : 4; | ||
1550 | uint64_t tx_bs_enh : 1; /**< Transmit Bit Stuffing on [15:8]. | ||
1551 | Enables or disables bit stuffing on data[15:8] | ||
1552 | when bit-stuffing is enabled. */ | ||
1553 | uint64_t tx_bs_en : 1; /**< Transmit Bit Stuffing on [7:0]. | ||
1554 | Enables or disables bit stuffing on data[7:0] | ||
1555 | when bit-stuffing is enabled. */ | ||
1556 | uint64_t loop_enb : 1; /**< PHY Loopback Test Enable. | ||
1557 | '1': During data transmission the receive is | ||
1558 | enabled. | ||
1559 | '0': During data transmission the receive is | ||
1560 | disabled. | ||
1561 | Must be '0' for normal operation. */ | ||
1562 | uint64_t vtest_enb : 1; /**< Analog Test Pin Enable. | ||
1563 | '1' The PHY's analog_test pin is enabled for the | ||
1564 | input and output of applicable analog test signals. | ||
1565 | '0' THe analog_test pin is disabled. */ | ||
1566 | uint64_t bist_enb : 1; /**< Built-In Self Test Enable. | ||
1567 | Used to activate BIST in the PHY. */ | ||
1568 | uint64_t tdata_sel : 1; /**< Test Data Out Select. | ||
1569 | '1' test_data_out[3:0] (PHY) register contents | ||
1570 | are output. '0' internaly generated signals are | ||
1571 | output. */ | ||
1572 | uint64_t taddr_in : 4; /**< Mode Address for Test Interface. | ||
1573 | Specifies the register address for writing to or | ||
1574 | reading from the PHY test interface register. */ | ||
1575 | uint64_t tdata_in : 8; /**< Internal Testing Register Input Data and Select | ||
1576 | This is a test bus. Data is present on [3:0], | ||
1577 | and its corresponding select (enable) is present | ||
1578 | on bits [7:4]. */ | ||
1579 | uint64_t ate_reset : 1; /**< Reset input from automatic test equipment. | ||
1580 | This is a test signal. When the USB Core is | ||
1581 | powered up (not in Susned Mode), an automatic | ||
1582 | tester can use this to disable phy_clock and | ||
1583 | free_clk, then re-eanable them with an aligned | ||
1584 | phase. | ||
1585 | '1': The phy_clk and free_clk outputs are | ||
1586 | disabled. "0": The phy_clock and free_clk outputs | ||
1587 | are available within a specific period after the | ||
1588 | de-assertion. */ | ||
1589 | } cn52xx; | ||
1590 | struct cvmx_usbnx_usbp_ctl_status_cn50xx cn52xxp1; | ||
1591 | struct cvmx_usbnx_usbp_ctl_status_cn52xx cn56xx; | ||
1592 | struct cvmx_usbnx_usbp_ctl_status_cn50xx cn56xxp1; | ||
1593 | }; | ||
1594 | typedef union cvmx_usbnx_usbp_ctl_status cvmx_usbnx_usbp_ctl_status_t; | ||
1595 | |||
1596 | #endif | ||
diff --git a/drivers/staging/octeon-usb/octeon-hcd.c b/drivers/staging/octeon-usb/octeon-hcd.c new file mode 100644 index 000000000000..b78bd19babda --- /dev/null +++ b/drivers/staging/octeon-usb/octeon-hcd.c | |||
@@ -0,0 +1,854 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2008 Cavium Networks | ||
7 | */ | ||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/module.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/pci.h> | ||
12 | #include <linux/interrupt.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/usb.h> | ||
16 | |||
17 | #include <asm/time.h> | ||
18 | #include <asm/delay.h> | ||
19 | |||
20 | #include <asm/octeon/cvmx.h> | ||
21 | #include "cvmx-usb.h" | ||
22 | #include <asm/octeon/cvmx-iob-defs.h> | ||
23 | |||
24 | #include <linux/usb/hcd.h> | ||
25 | |||
26 | //#define DEBUG_CALL(format, ...) printk(format, ##__VA_ARGS__) | ||
27 | #define DEBUG_CALL(format, ...) do {} while (0) | ||
28 | //#define DEBUG_SUBMIT(format, ...) printk(format, ##__VA_ARGS__) | ||
29 | #define DEBUG_SUBMIT(format, ...) do {} while (0) | ||
30 | //#define DEBUG_ROOT_HUB(format, ...) printk(format, ##__VA_ARGS__) | ||
31 | #define DEBUG_ROOT_HUB(format, ...) do {} while (0) | ||
32 | //#define DEBUG_ERROR(format, ...) printk(format, ##__VA_ARGS__) | ||
33 | #define DEBUG_ERROR(format, ...) do {} while (0) | ||
34 | #define DEBUG_FATAL(format, ...) printk(format, ##__VA_ARGS__) | ||
35 | |||
36 | struct octeon_hcd { | ||
37 | spinlock_t lock; | ||
38 | cvmx_usb_state_t usb; | ||
39 | struct tasklet_struct dequeue_tasklet; | ||
40 | struct list_head dequeue_list; | ||
41 | }; | ||
42 | |||
43 | /* convert between an HCD pointer and the corresponding struct octeon_hcd */ | ||
44 | static inline struct octeon_hcd *hcd_to_octeon(struct usb_hcd *hcd) | ||
45 | { | ||
46 | return (struct octeon_hcd *)(hcd->hcd_priv); | ||
47 | } | ||
48 | |||
49 | static inline struct usb_hcd *octeon_to_hcd(struct octeon_hcd *p) | ||
50 | { | ||
51 | return container_of((void *)p, struct usb_hcd, hcd_priv); | ||
52 | } | ||
53 | |||
54 | static inline struct octeon_hcd *cvmx_usb_to_octeon(cvmx_usb_state_t *p) | ||
55 | { | ||
56 | return container_of(p, struct octeon_hcd, usb); | ||
57 | } | ||
58 | |||
59 | static irqreturn_t octeon_usb_irq(struct usb_hcd *hcd) | ||
60 | { | ||
61 | struct octeon_hcd *priv = hcd_to_octeon(hcd); | ||
62 | unsigned long flags; | ||
63 | DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__); | ||
64 | spin_lock_irqsave(&priv->lock, flags); | ||
65 | cvmx_usb_poll(&priv->usb); | ||
66 | spin_unlock_irqrestore(&priv->lock, flags); | ||
67 | return IRQ_HANDLED; | ||
68 | } | ||
69 | |||
70 | static void octeon_usb_port_callback(cvmx_usb_state_t *usb, | ||
71 | cvmx_usb_callback_t reason, | ||
72 | cvmx_usb_complete_t status, | ||
73 | int pipe_handle, | ||
74 | int submit_handle, | ||
75 | int bytes_transferred, | ||
76 | void *user_data) | ||
77 | { | ||
78 | struct octeon_hcd *priv = cvmx_usb_to_octeon(usb); | ||
79 | DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__); | ||
80 | spin_unlock(&priv->lock); | ||
81 | usb_hcd_poll_rh_status(octeon_to_hcd(priv)); | ||
82 | spin_lock(&priv->lock); | ||
83 | } | ||
84 | |||
85 | static int octeon_usb_start(struct usb_hcd *hcd) | ||
86 | { | ||
87 | struct octeon_hcd *priv = hcd_to_octeon(hcd); | ||
88 | unsigned long flags; | ||
89 | DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__); | ||
90 | hcd->state = HC_STATE_RUNNING; | ||
91 | spin_lock_irqsave(&priv->lock, flags); | ||
92 | cvmx_usb_register_callback(&priv->usb, CVMX_USB_CALLBACK_PORT_CHANGED, | ||
93 | octeon_usb_port_callback, NULL); | ||
94 | spin_unlock_irqrestore(&priv->lock, flags); | ||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | static void octeon_usb_stop(struct usb_hcd *hcd) | ||
99 | { | ||
100 | struct octeon_hcd *priv = hcd_to_octeon(hcd); | ||
101 | unsigned long flags; | ||
102 | DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__); | ||
103 | spin_lock_irqsave(&priv->lock, flags); | ||
104 | cvmx_usb_register_callback(&priv->usb, CVMX_USB_CALLBACK_PORT_CHANGED, | ||
105 | NULL, NULL); | ||
106 | spin_unlock_irqrestore(&priv->lock, flags); | ||
107 | hcd->state = HC_STATE_HALT; | ||
108 | } | ||
109 | |||
110 | static int octeon_usb_get_frame_number(struct usb_hcd *hcd) | ||
111 | { | ||
112 | struct octeon_hcd *priv = hcd_to_octeon(hcd); | ||
113 | DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__); | ||
114 | return cvmx_usb_get_frame_number(&priv->usb); | ||
115 | } | ||
116 | |||
117 | static void octeon_usb_urb_complete_callback(cvmx_usb_state_t *usb, | ||
118 | cvmx_usb_callback_t reason, | ||
119 | cvmx_usb_complete_t status, | ||
120 | int pipe_handle, | ||
121 | int submit_handle, | ||
122 | int bytes_transferred, | ||
123 | void *user_data) | ||
124 | { | ||
125 | struct octeon_hcd *priv = cvmx_usb_to_octeon(usb); | ||
126 | struct urb *urb = user_data; | ||
127 | DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__); | ||
128 | urb->actual_length = bytes_transferred; | ||
129 | urb->hcpriv = NULL; | ||
130 | |||
131 | if (!list_empty(&urb->urb_list)) { | ||
132 | /* | ||
133 | * It is on the dequeue_list, but we are going to call | ||
134 | * usb_hcd_giveback_urb(), so we must clear it from | ||
135 | * the list. We got to it before the | ||
136 | * octeon_usb_urb_dequeue_work() tasklet did. | ||
137 | */ | ||
138 | list_del(&urb->urb_list); | ||
139 | /* No longer on the dequeue_list. */ | ||
140 | INIT_LIST_HEAD(&urb->urb_list); | ||
141 | } | ||
142 | |||
143 | /* For Isochronous transactions we need to update the URB packet status | ||
144 | list from data in our private copy */ | ||
145 | if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) | ||
146 | { | ||
147 | int i; | ||
148 | /* The pointer to the private list is stored in the setup_packet field */ | ||
149 | cvmx_usb_iso_packet_t *iso_packet = (cvmx_usb_iso_packet_t *)urb->setup_packet; | ||
150 | /* Recalculate the transfer size by adding up each packet */ | ||
151 | urb->actual_length = 0; | ||
152 | for (i=0; i<urb->number_of_packets; i++) | ||
153 | { | ||
154 | if (iso_packet[i].status == CVMX_USB_COMPLETE_SUCCESS) | ||
155 | { | ||
156 | urb->iso_frame_desc[i].status = 0; | ||
157 | urb->iso_frame_desc[i].actual_length = iso_packet[i].length; | ||
158 | urb->actual_length += urb->iso_frame_desc[i].actual_length; | ||
159 | } | ||
160 | else | ||
161 | { | ||
162 | DEBUG_ERROR("%s: ISOCHRONOUS packet=%d of %d status=%d pipe=%d submit=%d size=%d\n", | ||
163 | __FUNCTION__, i, urb->number_of_packets, | ||
164 | iso_packet[i].status, pipe_handle, | ||
165 | submit_handle, iso_packet[i].length); | ||
166 | urb->iso_frame_desc[i].status = -EREMOTEIO; | ||
167 | } | ||
168 | } | ||
169 | /* Free the private list now that we don't need it anymore */ | ||
170 | kfree(iso_packet); | ||
171 | urb->setup_packet = NULL; | ||
172 | } | ||
173 | |||
174 | switch (status) | ||
175 | { | ||
176 | case CVMX_USB_COMPLETE_SUCCESS: | ||
177 | urb->status = 0; | ||
178 | break; | ||
179 | case CVMX_USB_COMPLETE_CANCEL: | ||
180 | if (urb->status == 0) | ||
181 | urb->status = -ENOENT; | ||
182 | break; | ||
183 | case CVMX_USB_COMPLETE_STALL: | ||
184 | DEBUG_ERROR("%s: status=stall pipe=%d submit=%d size=%d\n", __FUNCTION__, pipe_handle, submit_handle, bytes_transferred); | ||
185 | urb->status = -EPIPE; | ||
186 | break; | ||
187 | case CVMX_USB_COMPLETE_BABBLEERR: | ||
188 | DEBUG_ERROR("%s: status=babble pipe=%d submit=%d size=%d\n", __FUNCTION__, pipe_handle, submit_handle, bytes_transferred); | ||
189 | urb->status = -EPIPE; | ||
190 | break; | ||
191 | case CVMX_USB_COMPLETE_SHORT: | ||
192 | DEBUG_ERROR("%s: status=short pipe=%d submit=%d size=%d\n", __FUNCTION__, pipe_handle, submit_handle, bytes_transferred); | ||
193 | urb->status = -EREMOTEIO; | ||
194 | break; | ||
195 | case CVMX_USB_COMPLETE_ERROR: | ||
196 | case CVMX_USB_COMPLETE_XACTERR: | ||
197 | case CVMX_USB_COMPLETE_DATATGLERR: | ||
198 | case CVMX_USB_COMPLETE_FRAMEERR: | ||
199 | DEBUG_ERROR("%s: status=%d pipe=%d submit=%d size=%d\n", __FUNCTION__, status, pipe_handle, submit_handle, bytes_transferred); | ||
200 | urb->status = -EPROTO; | ||
201 | break; | ||
202 | } | ||
203 | spin_unlock(&priv->lock); | ||
204 | usb_hcd_giveback_urb(octeon_to_hcd(priv), urb, urb->status); | ||
205 | spin_lock(&priv->lock); | ||
206 | } | ||
207 | |||
208 | static int octeon_usb_urb_enqueue(struct usb_hcd *hcd, | ||
209 | struct urb *urb, | ||
210 | gfp_t mem_flags) | ||
211 | { | ||
212 | struct octeon_hcd *priv = hcd_to_octeon(hcd); | ||
213 | int submit_handle = -1; | ||
214 | int pipe_handle; | ||
215 | unsigned long flags; | ||
216 | cvmx_usb_iso_packet_t *iso_packet; | ||
217 | struct usb_host_endpoint *ep = urb->ep; | ||
218 | |||
219 | DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__); | ||
220 | |||
221 | urb->status = 0; | ||
222 | INIT_LIST_HEAD(&urb->urb_list); /* not enqueued on dequeue_list */ | ||
223 | spin_lock_irqsave(&priv->lock, flags); | ||
224 | |||
225 | if (!ep->hcpriv) | ||
226 | { | ||
227 | cvmx_usb_transfer_t transfer_type; | ||
228 | cvmx_usb_speed_t speed; | ||
229 | int split_device = 0; | ||
230 | int split_port = 0; | ||
231 | switch (usb_pipetype(urb->pipe)) | ||
232 | { | ||
233 | case PIPE_ISOCHRONOUS: | ||
234 | transfer_type = CVMX_USB_TRANSFER_ISOCHRONOUS; | ||
235 | break; | ||
236 | case PIPE_INTERRUPT: | ||
237 | transfer_type = CVMX_USB_TRANSFER_INTERRUPT; | ||
238 | break; | ||
239 | case PIPE_CONTROL: | ||
240 | transfer_type = CVMX_USB_TRANSFER_CONTROL; | ||
241 | break; | ||
242 | default: | ||
243 | transfer_type = CVMX_USB_TRANSFER_BULK; | ||
244 | break; | ||
245 | } | ||
246 | switch (urb->dev->speed) | ||
247 | { | ||
248 | case USB_SPEED_LOW: | ||
249 | speed = CVMX_USB_SPEED_LOW; | ||
250 | break; | ||
251 | case USB_SPEED_FULL: | ||
252 | speed = CVMX_USB_SPEED_FULL; | ||
253 | break; | ||
254 | default: | ||
255 | speed = CVMX_USB_SPEED_HIGH; | ||
256 | break; | ||
257 | } | ||
258 | /* For slow devices on high speed ports we need to find the hub that | ||
259 | does the speed translation so we know where to send the split | ||
260 | transactions */ | ||
261 | if (speed != CVMX_USB_SPEED_HIGH) | ||
262 | { | ||
263 | /* Start at this device and work our way up the usb tree */ | ||
264 | struct usb_device *dev = urb->dev; | ||
265 | while (dev->parent) | ||
266 | { | ||
267 | /* If our parent is high speed then he'll receive the splits */ | ||
268 | if (dev->parent->speed == USB_SPEED_HIGH) | ||
269 | { | ||
270 | split_device = dev->parent->devnum; | ||
271 | split_port = dev->portnum; | ||
272 | break; | ||
273 | } | ||
274 | /* Move up the tree one level. If we make it all the way up the | ||
275 | tree, then the port must not be in high speed mode and we | ||
276 | don't need a split */ | ||
277 | dev = dev->parent; | ||
278 | } | ||
279 | } | ||
280 | pipe_handle = cvmx_usb_open_pipe(&priv->usb, | ||
281 | 0, | ||
282 | usb_pipedevice(urb->pipe), | ||
283 | usb_pipeendpoint(urb->pipe), | ||
284 | speed, | ||
285 | le16_to_cpu(ep->desc.wMaxPacketSize) & 0x7ff, | ||
286 | transfer_type, | ||
287 | usb_pipein(urb->pipe) ? CVMX_USB_DIRECTION_IN : CVMX_USB_DIRECTION_OUT, | ||
288 | urb->interval, | ||
289 | (le16_to_cpu(ep->desc.wMaxPacketSize)>>11) & 0x3, | ||
290 | split_device, | ||
291 | split_port); | ||
292 | if (pipe_handle < 0) | ||
293 | { | ||
294 | spin_unlock_irqrestore(&priv->lock, flags); | ||
295 | DEBUG_ERROR("OcteonUSB: %s failed to create pipe\n", __FUNCTION__); | ||
296 | return -ENOMEM; | ||
297 | } | ||
298 | ep->hcpriv = (void*)(0x10000L + pipe_handle); | ||
299 | } | ||
300 | else | ||
301 | pipe_handle = 0xffff & (long)ep->hcpriv; | ||
302 | |||
303 | switch (usb_pipetype(urb->pipe)) | ||
304 | { | ||
305 | case PIPE_ISOCHRONOUS: | ||
306 | DEBUG_SUBMIT("OcteonUSB: %s submit isochronous to %d.%d\n", __FUNCTION__, usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe)); | ||
307 | /* Allocate a structure to use for our private list of isochronous | ||
308 | packets */ | ||
309 | iso_packet = kmalloc(urb->number_of_packets * sizeof(cvmx_usb_iso_packet_t), GFP_ATOMIC); | ||
310 | if (iso_packet) | ||
311 | { | ||
312 | int i; | ||
313 | /* Fill the list with the data from the URB */ | ||
314 | for (i=0; i<urb->number_of_packets; i++) | ||
315 | { | ||
316 | iso_packet[i].offset = urb->iso_frame_desc[i].offset; | ||
317 | iso_packet[i].length = urb->iso_frame_desc[i].length; | ||
318 | iso_packet[i].status = CVMX_USB_COMPLETE_ERROR; | ||
319 | } | ||
320 | /* Store a pointer to the list in uthe URB setup_pakcet field. | ||
321 | We know this currently isn't being used and this saves us | ||
322 | a bunch of logic */ | ||
323 | urb->setup_packet = (char*)iso_packet; | ||
324 | submit_handle = cvmx_usb_submit_isochronous(&priv->usb, pipe_handle, | ||
325 | urb->start_frame, | ||
326 | 0 /* flags */, | ||
327 | urb->number_of_packets, | ||
328 | iso_packet, | ||
329 | urb->transfer_dma, | ||
330 | urb->transfer_buffer_length, | ||
331 | octeon_usb_urb_complete_callback, | ||
332 | urb); | ||
333 | /* If submit failed we need to free our private packet list */ | ||
334 | if (submit_handle < 0) | ||
335 | { | ||
336 | urb->setup_packet = NULL; | ||
337 | kfree(iso_packet); | ||
338 | } | ||
339 | } | ||
340 | break; | ||
341 | case PIPE_INTERRUPT: | ||
342 | DEBUG_SUBMIT("OcteonUSB: %s submit interrupt to %d.%d\n", __FUNCTION__, usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe)); | ||
343 | submit_handle = cvmx_usb_submit_interrupt(&priv->usb, pipe_handle, | ||
344 | urb->transfer_dma, | ||
345 | urb->transfer_buffer_length, | ||
346 | octeon_usb_urb_complete_callback, | ||
347 | urb); | ||
348 | break; | ||
349 | case PIPE_CONTROL: | ||
350 | DEBUG_SUBMIT("OcteonUSB: %s submit control to %d.%d\n", __FUNCTION__, usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe)); | ||
351 | submit_handle = cvmx_usb_submit_control(&priv->usb, pipe_handle, | ||
352 | urb->setup_dma, | ||
353 | urb->transfer_dma, | ||
354 | urb->transfer_buffer_length, | ||
355 | octeon_usb_urb_complete_callback, | ||
356 | urb); | ||
357 | break; | ||
358 | case PIPE_BULK: | ||
359 | DEBUG_SUBMIT("OcteonUSB: %s submit bulk to %d.%d\n", __FUNCTION__, usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe)); | ||
360 | submit_handle = cvmx_usb_submit_bulk(&priv->usb, pipe_handle, | ||
361 | urb->transfer_dma, | ||
362 | urb->transfer_buffer_length, | ||
363 | octeon_usb_urb_complete_callback, | ||
364 | urb); | ||
365 | break; | ||
366 | } | ||
367 | if (submit_handle < 0) | ||
368 | { | ||
369 | spin_unlock_irqrestore(&priv->lock, flags); | ||
370 | DEBUG_ERROR("OcteonUSB: %s failed to submit\n", __FUNCTION__); | ||
371 | return -ENOMEM; | ||
372 | } | ||
373 | urb->hcpriv = (void*)(long)(((submit_handle & 0xffff) << 16) | pipe_handle); | ||
374 | spin_unlock_irqrestore(&priv->lock, flags); | ||
375 | return 0; | ||
376 | } | ||
377 | |||
378 | static void octeon_usb_urb_dequeue_work(unsigned long arg) | ||
379 | { | ||
380 | unsigned long flags; | ||
381 | struct octeon_hcd *priv = (struct octeon_hcd *)arg; | ||
382 | |||
383 | spin_lock_irqsave(&priv->lock, flags); | ||
384 | |||
385 | while (!list_empty(&priv->dequeue_list)) { | ||
386 | int pipe_handle; | ||
387 | int submit_handle; | ||
388 | struct urb *urb = container_of(priv->dequeue_list.next, struct urb, urb_list); | ||
389 | list_del(&urb->urb_list); | ||
390 | /* not enqueued on dequeue_list */ | ||
391 | INIT_LIST_HEAD(&urb->urb_list); | ||
392 | pipe_handle = 0xffff & (long)urb->hcpriv; | ||
393 | submit_handle = ((long)urb->hcpriv) >> 16; | ||
394 | cvmx_usb_cancel(&priv->usb, pipe_handle, submit_handle); | ||
395 | } | ||
396 | |||
397 | spin_unlock_irqrestore(&priv->lock, flags); | ||
398 | } | ||
399 | |||
400 | static int octeon_usb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | ||
401 | { | ||
402 | struct octeon_hcd *priv = hcd_to_octeon(hcd); | ||
403 | unsigned long flags; | ||
404 | |||
405 | DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__); | ||
406 | |||
407 | if (!urb->dev) | ||
408 | return -EINVAL; | ||
409 | |||
410 | spin_lock_irqsave(&priv->lock, flags); | ||
411 | |||
412 | urb->status = status; | ||
413 | list_add_tail(&urb->urb_list, &priv->dequeue_list); | ||
414 | |||
415 | spin_unlock_irqrestore(&priv->lock, flags); | ||
416 | |||
417 | tasklet_schedule(&priv->dequeue_tasklet); | ||
418 | |||
419 | return 0; | ||
420 | } | ||
421 | |||
422 | static void octeon_usb_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep) | ||
423 | { | ||
424 | DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__); | ||
425 | if (ep->hcpriv) | ||
426 | { | ||
427 | struct octeon_hcd *priv = hcd_to_octeon(hcd); | ||
428 | int pipe_handle = 0xffff & (long)ep->hcpriv; | ||
429 | unsigned long flags; | ||
430 | spin_lock_irqsave(&priv->lock, flags); | ||
431 | cvmx_usb_cancel_all(&priv->usb, pipe_handle); | ||
432 | if (cvmx_usb_close_pipe(&priv->usb, pipe_handle)) | ||
433 | DEBUG_ERROR("OcteonUSB: Closing pipe %d failed\n", pipe_handle); | ||
434 | spin_unlock_irqrestore(&priv->lock, flags); | ||
435 | ep->hcpriv = NULL; | ||
436 | } | ||
437 | } | ||
438 | |||
439 | static int octeon_usb_hub_status_data(struct usb_hcd *hcd, char *buf) | ||
440 | { | ||
441 | struct octeon_hcd *priv = hcd_to_octeon(hcd); | ||
442 | cvmx_usb_port_status_t port_status; | ||
443 | unsigned long flags; | ||
444 | |||
445 | DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__); | ||
446 | |||
447 | spin_lock_irqsave(&priv->lock, flags); | ||
448 | port_status = cvmx_usb_get_status(&priv->usb); | ||
449 | spin_unlock_irqrestore(&priv->lock, flags); | ||
450 | buf[0] = 0; | ||
451 | buf[0] = port_status.connect_change << 1; | ||
452 | |||
453 | return(buf[0] != 0); | ||
454 | } | ||
455 | |||
456 | static int octeon_usb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength) | ||
457 | { | ||
458 | struct octeon_hcd *priv = hcd_to_octeon(hcd); | ||
459 | cvmx_usb_port_status_t usb_port_status; | ||
460 | int port_status; | ||
461 | struct usb_hub_descriptor *desc; | ||
462 | unsigned long flags; | ||
463 | |||
464 | switch (typeReq) | ||
465 | { | ||
466 | case ClearHubFeature: | ||
467 | DEBUG_ROOT_HUB("OcteonUSB: ClearHubFeature\n"); | ||
468 | switch (wValue) | ||
469 | { | ||
470 | case C_HUB_LOCAL_POWER: | ||
471 | case C_HUB_OVER_CURRENT: | ||
472 | /* Nothing required here */ | ||
473 | break; | ||
474 | default: | ||
475 | return -EINVAL; | ||
476 | } | ||
477 | break; | ||
478 | case ClearPortFeature: | ||
479 | DEBUG_ROOT_HUB("OcteonUSB: ClearPortFeature"); | ||
480 | if (wIndex != 1) | ||
481 | { | ||
482 | DEBUG_ROOT_HUB(" INVALID\n"); | ||
483 | return -EINVAL; | ||
484 | } | ||
485 | |||
486 | switch (wValue) | ||
487 | { | ||
488 | case USB_PORT_FEAT_ENABLE: | ||
489 | DEBUG_ROOT_HUB(" ENABLE"); | ||
490 | spin_lock_irqsave(&priv->lock, flags); | ||
491 | cvmx_usb_disable(&priv->usb); | ||
492 | spin_unlock_irqrestore(&priv->lock, flags); | ||
493 | break; | ||
494 | case USB_PORT_FEAT_SUSPEND: | ||
495 | DEBUG_ROOT_HUB(" SUSPEND"); | ||
496 | /* Not supported on Octeon */ | ||
497 | break; | ||
498 | case USB_PORT_FEAT_POWER: | ||
499 | DEBUG_ROOT_HUB(" POWER"); | ||
500 | /* Not supported on Octeon */ | ||
501 | break; | ||
502 | case USB_PORT_FEAT_INDICATOR: | ||
503 | DEBUG_ROOT_HUB(" INDICATOR"); | ||
504 | /* Port inidicator not supported */ | ||
505 | break; | ||
506 | case USB_PORT_FEAT_C_CONNECTION: | ||
507 | DEBUG_ROOT_HUB(" C_CONNECTION"); | ||
508 | /* Clears drivers internal connect status change flag */ | ||
509 | spin_lock_irqsave(&priv->lock, flags); | ||
510 | cvmx_usb_set_status(&priv->usb, cvmx_usb_get_status(&priv->usb)); | ||
511 | spin_unlock_irqrestore(&priv->lock, flags); | ||
512 | break; | ||
513 | case USB_PORT_FEAT_C_RESET: | ||
514 | DEBUG_ROOT_HUB(" C_RESET"); | ||
515 | /* Clears the driver's internal Port Reset Change flag */ | ||
516 | spin_lock_irqsave(&priv->lock, flags); | ||
517 | cvmx_usb_set_status(&priv->usb, cvmx_usb_get_status(&priv->usb)); | ||
518 | spin_unlock_irqrestore(&priv->lock, flags); | ||
519 | break; | ||
520 | case USB_PORT_FEAT_C_ENABLE: | ||
521 | DEBUG_ROOT_HUB(" C_ENABLE"); | ||
522 | /* Clears the driver's internal Port Enable/Disable Change flag */ | ||
523 | spin_lock_irqsave(&priv->lock, flags); | ||
524 | cvmx_usb_set_status(&priv->usb, cvmx_usb_get_status(&priv->usb)); | ||
525 | spin_unlock_irqrestore(&priv->lock, flags); | ||
526 | break; | ||
527 | case USB_PORT_FEAT_C_SUSPEND: | ||
528 | DEBUG_ROOT_HUB(" C_SUSPEND"); | ||
529 | /* Clears the driver's internal Port Suspend Change flag, | ||
530 | which is set when resume signaling on the host port is | ||
531 | complete */ | ||
532 | break; | ||
533 | case USB_PORT_FEAT_C_OVER_CURRENT: | ||
534 | DEBUG_ROOT_HUB(" C_OVER_CURRENT"); | ||
535 | /* Clears the driver's overcurrent Change flag */ | ||
536 | spin_lock_irqsave(&priv->lock, flags); | ||
537 | cvmx_usb_set_status(&priv->usb, cvmx_usb_get_status(&priv->usb)); | ||
538 | spin_unlock_irqrestore(&priv->lock, flags); | ||
539 | break; | ||
540 | default: | ||
541 | DEBUG_ROOT_HUB(" UNKNOWN\n"); | ||
542 | return -EINVAL; | ||
543 | } | ||
544 | DEBUG_ROOT_HUB("\n"); | ||
545 | break; | ||
546 | case GetHubDescriptor: | ||
547 | DEBUG_ROOT_HUB("OcteonUSB: GetHubDescriptor\n"); | ||
548 | desc = (struct usb_hub_descriptor *)buf; | ||
549 | desc->bDescLength = 9; | ||
550 | desc->bDescriptorType = 0x29; | ||
551 | desc->bNbrPorts = 1; | ||
552 | desc->wHubCharacteristics = 0x08; | ||
553 | desc->bPwrOn2PwrGood = 1; | ||
554 | desc->bHubContrCurrent = 0; | ||
555 | desc->u.hs.DeviceRemovable[0] = 0; | ||
556 | desc->u.hs.DeviceRemovable[1] = 0xff; | ||
557 | break; | ||
558 | case GetHubStatus: | ||
559 | DEBUG_ROOT_HUB("OcteonUSB: GetHubStatus\n"); | ||
560 | *(__le32 *)buf = 0; | ||
561 | break; | ||
562 | case GetPortStatus: | ||
563 | DEBUG_ROOT_HUB("OcteonUSB: GetPortStatus"); | ||
564 | if (wIndex != 1) | ||
565 | { | ||
566 | DEBUG_ROOT_HUB(" INVALID\n"); | ||
567 | return -EINVAL; | ||
568 | } | ||
569 | |||
570 | spin_lock_irqsave(&priv->lock, flags); | ||
571 | usb_port_status = cvmx_usb_get_status(&priv->usb); | ||
572 | spin_unlock_irqrestore(&priv->lock, flags); | ||
573 | port_status = 0; | ||
574 | |||
575 | if (usb_port_status.connect_change) | ||
576 | { | ||
577 | port_status |= (1 << USB_PORT_FEAT_C_CONNECTION); | ||
578 | DEBUG_ROOT_HUB(" C_CONNECTION"); | ||
579 | } | ||
580 | |||
581 | if (usb_port_status.port_enabled) | ||
582 | { | ||
583 | port_status |= (1 << USB_PORT_FEAT_C_ENABLE); | ||
584 | DEBUG_ROOT_HUB(" C_ENABLE"); | ||
585 | } | ||
586 | |||
587 | if (usb_port_status.connected) | ||
588 | { | ||
589 | port_status |= (1 << USB_PORT_FEAT_CONNECTION); | ||
590 | DEBUG_ROOT_HUB(" CONNECTION"); | ||
591 | } | ||
592 | |||
593 | if (usb_port_status.port_enabled) | ||
594 | { | ||
595 | port_status |= (1 << USB_PORT_FEAT_ENABLE); | ||
596 | DEBUG_ROOT_HUB(" ENABLE"); | ||
597 | } | ||
598 | |||
599 | if (usb_port_status.port_over_current) | ||
600 | { | ||
601 | port_status |= (1 << USB_PORT_FEAT_OVER_CURRENT); | ||
602 | DEBUG_ROOT_HUB(" OVER_CURRENT"); | ||
603 | } | ||
604 | |||
605 | if (usb_port_status.port_powered) | ||
606 | { | ||
607 | port_status |= (1 << USB_PORT_FEAT_POWER); | ||
608 | DEBUG_ROOT_HUB(" POWER"); | ||
609 | } | ||
610 | |||
611 | if (usb_port_status.port_speed == CVMX_USB_SPEED_HIGH) | ||
612 | { | ||
613 | port_status |= USB_PORT_STAT_HIGH_SPEED; | ||
614 | DEBUG_ROOT_HUB(" HIGHSPEED"); | ||
615 | } | ||
616 | else if (usb_port_status.port_speed == CVMX_USB_SPEED_LOW) | ||
617 | { | ||
618 | port_status |= (1 << USB_PORT_FEAT_LOWSPEED); | ||
619 | DEBUG_ROOT_HUB(" LOWSPEED"); | ||
620 | } | ||
621 | |||
622 | *((__le32 *)buf) = cpu_to_le32(port_status); | ||
623 | DEBUG_ROOT_HUB("\n"); | ||
624 | break; | ||
625 | case SetHubFeature: | ||
626 | DEBUG_ROOT_HUB("OcteonUSB: SetHubFeature\n"); | ||
627 | /* No HUB features supported */ | ||
628 | break; | ||
629 | case SetPortFeature: | ||
630 | DEBUG_ROOT_HUB("OcteonUSB: SetPortFeature"); | ||
631 | if (wIndex != 1) | ||
632 | { | ||
633 | DEBUG_ROOT_HUB(" INVALID\n"); | ||
634 | return -EINVAL; | ||
635 | } | ||
636 | |||
637 | switch (wValue) | ||
638 | { | ||
639 | case USB_PORT_FEAT_SUSPEND: | ||
640 | DEBUG_ROOT_HUB(" SUSPEND\n"); | ||
641 | return -EINVAL; | ||
642 | case USB_PORT_FEAT_POWER: | ||
643 | DEBUG_ROOT_HUB(" POWER\n"); | ||
644 | return -EINVAL; | ||
645 | case USB_PORT_FEAT_RESET: | ||
646 | DEBUG_ROOT_HUB(" RESET\n"); | ||
647 | spin_lock_irqsave(&priv->lock, flags); | ||
648 | cvmx_usb_disable(&priv->usb); | ||
649 | if (cvmx_usb_enable(&priv->usb)) | ||
650 | DEBUG_ERROR("Failed to enable the port\n"); | ||
651 | spin_unlock_irqrestore(&priv->lock, flags); | ||
652 | return 0; | ||
653 | case USB_PORT_FEAT_INDICATOR: | ||
654 | DEBUG_ROOT_HUB(" INDICATOR\n"); | ||
655 | /* Not supported */ | ||
656 | break; | ||
657 | default: | ||
658 | DEBUG_ROOT_HUB(" UNKNOWN\n"); | ||
659 | return -EINVAL; | ||
660 | } | ||
661 | break; | ||
662 | default: | ||
663 | DEBUG_ROOT_HUB("OcteonUSB: Unknown root hub request\n"); | ||
664 | return -EINVAL; | ||
665 | } | ||
666 | return 0; | ||
667 | } | ||
668 | |||
669 | |||
670 | static const struct hc_driver octeon_hc_driver = { | ||
671 | .description = "Octeon USB", | ||
672 | .product_desc = "Octeon Host Controller", | ||
673 | .hcd_priv_size = sizeof(struct octeon_hcd), | ||
674 | .irq = octeon_usb_irq, | ||
675 | .flags = HCD_MEMORY | HCD_USB2, | ||
676 | .start = octeon_usb_start, | ||
677 | .stop = octeon_usb_stop, | ||
678 | .urb_enqueue = octeon_usb_urb_enqueue, | ||
679 | .urb_dequeue = octeon_usb_urb_dequeue, | ||
680 | .endpoint_disable = octeon_usb_endpoint_disable, | ||
681 | .get_frame_number = octeon_usb_get_frame_number, | ||
682 | .hub_status_data = octeon_usb_hub_status_data, | ||
683 | .hub_control = octeon_usb_hub_control, | ||
684 | }; | ||
685 | |||
686 | |||
687 | static int octeon_usb_driver_probe(struct device *dev) | ||
688 | { | ||
689 | int status; | ||
690 | int usb_num = to_platform_device(dev)->id; | ||
691 | int irq = platform_get_irq(to_platform_device(dev), 0); | ||
692 | struct octeon_hcd *priv; | ||
693 | struct usb_hcd *hcd; | ||
694 | unsigned long flags; | ||
695 | |||
696 | DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__); | ||
697 | |||
698 | /* Set the DMA mask to 64bits so we get buffers already translated for | ||
699 | DMA */ | ||
700 | dev->coherent_dma_mask = ~0; | ||
701 | dev->dma_mask = &dev->coherent_dma_mask; | ||
702 | |||
703 | hcd = usb_create_hcd(&octeon_hc_driver, dev, dev_name(dev)); | ||
704 | if (!hcd) | ||
705 | { | ||
706 | DEBUG_FATAL("OcteonUSB: Failed to allocate memory for HCD\n"); | ||
707 | return -1; | ||
708 | } | ||
709 | hcd->uses_new_polling = 1; | ||
710 | priv = (struct octeon_hcd *)hcd->hcd_priv; | ||
711 | |||
712 | spin_lock_init(&priv->lock); | ||
713 | |||
714 | tasklet_init(&priv->dequeue_tasklet, octeon_usb_urb_dequeue_work, (unsigned long)priv); | ||
715 | INIT_LIST_HEAD(&priv->dequeue_list); | ||
716 | |||
717 | //status = cvmx_usb_initialize(&priv->usb, usb_num, CVMX_USB_INITIALIZE_FLAGS_CLOCK_AUTO | CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO | CVMX_USB_INITIALIZE_FLAGS_DEBUG_TRANSFERS | CVMX_USB_INITIALIZE_FLAGS_DEBUG_CALLBACKS); | ||
718 | status = cvmx_usb_initialize(&priv->usb, usb_num, CVMX_USB_INITIALIZE_FLAGS_CLOCK_AUTO); | ||
719 | if (status) | ||
720 | { | ||
721 | DEBUG_FATAL("OcteonUSB: USB initialization failed with %d\n", status); | ||
722 | kfree(hcd); | ||
723 | return -1; | ||
724 | } | ||
725 | |||
726 | /* This delay is needed for CN3010, but I don't know why... */ | ||
727 | mdelay(10); | ||
728 | |||
729 | spin_lock_irqsave(&priv->lock, flags); | ||
730 | cvmx_usb_poll(&priv->usb); | ||
731 | spin_unlock_irqrestore(&priv->lock, flags); | ||
732 | |||
733 | status = usb_add_hcd(hcd, irq, IRQF_SHARED); | ||
734 | if (status) | ||
735 | { | ||
736 | DEBUG_FATAL("OcteonUSB: USB add HCD failed with %d\n", status); | ||
737 | kfree(hcd); | ||
738 | return -1; | ||
739 | } | ||
740 | |||
741 | printk("OcteonUSB: Registered HCD for port %d on irq %d\n", usb_num, irq); | ||
742 | |||
743 | return 0; | ||
744 | } | ||
745 | |||
746 | static int octeon_usb_driver_remove(struct device *dev) | ||
747 | { | ||
748 | int status; | ||
749 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
750 | struct octeon_hcd *priv = hcd_to_octeon(hcd); | ||
751 | unsigned long flags; | ||
752 | |||
753 | DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__); | ||
754 | |||
755 | usb_remove_hcd(hcd); | ||
756 | tasklet_kill(&priv->dequeue_tasklet); | ||
757 | spin_lock_irqsave(&priv->lock, flags); | ||
758 | status = cvmx_usb_shutdown(&priv->usb); | ||
759 | spin_unlock_irqrestore(&priv->lock, flags); | ||
760 | if (status) | ||
761 | DEBUG_FATAL("OcteonUSB: USB shutdown failed with %d\n", status); | ||
762 | |||
763 | kfree(hcd); | ||
764 | |||
765 | return 0; | ||
766 | } | ||
767 | |||
768 | static struct device_driver octeon_usb_driver = { | ||
769 | .name = "OcteonUSB", | ||
770 | .bus = &platform_bus_type, | ||
771 | .probe = octeon_usb_driver_probe, | ||
772 | .remove = octeon_usb_driver_remove, | ||
773 | }; | ||
774 | |||
775 | |||
776 | #define MAX_USB_PORTS 10 | ||
777 | struct platform_device *pdev_glob[MAX_USB_PORTS]; | ||
778 | static int octeon_usb_registered; | ||
779 | static int __init octeon_usb_module_init(void) | ||
780 | { | ||
781 | int num_devices = cvmx_usb_get_num_ports(); | ||
782 | int device; | ||
783 | |||
784 | if (usb_disabled() || num_devices == 0) | ||
785 | return -ENODEV; | ||
786 | |||
787 | if (driver_register(&octeon_usb_driver)) | ||
788 | { | ||
789 | DEBUG_FATAL("OcteonUSB: Failed to register driver\n"); | ||
790 | return -ENOMEM; | ||
791 | } | ||
792 | octeon_usb_registered = 1; | ||
793 | printk("OcteonUSB: Detected %d ports\n", num_devices); | ||
794 | |||
795 | /* | ||
796 | * Only cn52XX and cn56XX have DWC_OTG USB hardware and the | ||
797 | * IOB priority registers. Under heavy network load USB | ||
798 | * hardware can be starved by the IOB causing a crash. Give | ||
799 | * it a priority boost if it has been waiting more than 400 | ||
800 | * cycles to avoid this situation. | ||
801 | * | ||
802 | * Testing indicates that a cnt_val of 8192 is not sufficient, | ||
803 | * but no failures are seen with 4096. We choose a value of | ||
804 | * 400 to give a safety factor of 10. | ||
805 | */ | ||
806 | if (OCTEON_IS_MODEL(OCTEON_CN52XX) || OCTEON_IS_MODEL(OCTEON_CN56XX)) { | ||
807 | union cvmx_iob_n2c_l2c_pri_cnt pri_cnt; | ||
808 | |||
809 | pri_cnt.u64 = 0; | ||
810 | pri_cnt.s.cnt_enb = 1; | ||
811 | pri_cnt.s.cnt_val = 400; | ||
812 | cvmx_write_csr(CVMX_IOB_N2C_L2C_PRI_CNT, pri_cnt.u64); | ||
813 | } | ||
814 | |||
815 | for (device = 0; device < num_devices; device++) | ||
816 | { | ||
817 | struct resource irq_resource; | ||
818 | struct platform_device *pdev; | ||
819 | memset(&irq_resource, 0, sizeof(irq_resource)); | ||
820 | irq_resource.start = (device==0) ? OCTEON_IRQ_USB0 : OCTEON_IRQ_USB1; | ||
821 | irq_resource.end = irq_resource.start; | ||
822 | irq_resource.flags = IORESOURCE_IRQ; | ||
823 | pdev = platform_device_register_simple((char*)octeon_usb_driver.name, device, &irq_resource, 1); | ||
824 | if (!pdev) | ||
825 | { | ||
826 | DEBUG_FATAL("OcteonUSB: Failed to allocate platform device for USB%d\n", device); | ||
827 | return -ENOMEM; | ||
828 | } | ||
829 | if (device < MAX_USB_PORTS) | ||
830 | pdev_glob[device] = pdev; | ||
831 | |||
832 | } | ||
833 | return 0; | ||
834 | } | ||
835 | |||
836 | static void __exit octeon_usb_module_cleanup(void) | ||
837 | { | ||
838 | int i; | ||
839 | DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__); | ||
840 | for (i = 0; i <MAX_USB_PORTS; i++) | ||
841 | if (pdev_glob[i]) | ||
842 | { | ||
843 | platform_device_unregister(pdev_glob[i]); | ||
844 | pdev_glob[i] = NULL; | ||
845 | } | ||
846 | if (octeon_usb_registered) | ||
847 | driver_unregister(&octeon_usb_driver); | ||
848 | } | ||
849 | |||
850 | MODULE_LICENSE("GPL"); | ||
851 | MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>"); | ||
852 | MODULE_DESCRIPTION("Cavium Networks Octeon USB Host driver."); | ||
853 | module_init(octeon_usb_module_init); | ||
854 | module_exit(octeon_usb_module_cleanup); | ||