1 /**************************************************************************/
2 /*                                                                        */
3 /*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4 /*                                                                        */
5 /*       This software is licensed under the Microsoft Software License   */
6 /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7 /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8 /*       and in the root directory of this software.                      */
9 /*                                                                        */
10 /**************************************************************************/
11 
12 
13 /**************************************************************************/
14 /**************************************************************************/
15 /**                                                                       */
16 /** USBX Component                                                        */
17 /**                                                                       */
18 /**   OHCI Controller Driver                                              */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 
24 /**************************************************************************/
25 /*                                                                        */
26 /*  COMPONENT DEFINITION                                   RELEASE        */
27 /*                                                                        */
28 /*    ux_hcd_ohci.h                                       PORTABLE C      */
29 /*                                                           6.1.12       */
30 /*  AUTHOR                                                                */
31 /*                                                                        */
32 /*    Chaoqiong Xiao, Microsoft Corporation                               */
33 /*                                                                        */
34 /*  DESCRIPTION                                                           */
35 /*                                                                        */
36 /*    This file contains all the header and extern functions used by the  */
37 /*    USBX host OHCI Controller.                                          */
38 /*                                                                        */
39 /*  RELEASE HISTORY                                                       */
40 /*                                                                        */
41 /*    DATE              NAME                      DESCRIPTION             */
42 /*                                                                        */
43 /*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
44 /*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
45 /*                                            resulting in version 6.1    */
46 /*  11-09-2020     Chaoqiong Xiao           Modified comment(s),          */
47 /*                                            used unsigned defines,      */
48 /*                                            resulting in version 6.1.2  */
49 /*  08-02-2021     Chaoqiong Xiao           Modified comment(s),          */
50 /*                                            added extern "C" keyword    */
51 /*                                            for compatibility with C++, */
52 /*                                            resulting in version 6.1.8  */
53 /*  01-31-2022     Xiuwen Cai               Modified comment(s),          */
54 /*                                            fixed HcPeriodicStart value,*/
55 /*                                            resulting in version 6.1.10 */
56 /*  07-29-2022     Yajun Xia                Modified comment(s),          */
57 /*                                            fixed OHCI PRSC issue,      */
58 /*                                            resulting in version 6.1.12 */
59 /*                                                                        */
60 /**************************************************************************/
61 
62 #ifndef UX_HCD_OHCI_H
63 #define UX_HCD_OHCI_H
64 
65 /* Determine if a C++ compiler is being used.  If so, ensure that standard
66    C is used to process the API information.  */
67 
68 #ifdef   __cplusplus
69 
70 /* Yes, C++ compiler is present.  Use standard C.  */
71 extern   "C" {
72 
73 #endif
74 
75 
76 /* Define generic OHCI constants.  */
77 
78 #define UX_OHCI_CONTROLLER                                  1
79 #define UX_OHCI_MAX_PAYLOAD                                 4096
80 #define UX_OHCI_FRAME_DELAY                                 4u
81 
82 
83 /* Define OHCI HCOR register mapping.  */
84 
85 #define OHCI_HC_REVISION                                    0x00
86 #define OHCI_HC_CONTROL                                     0x01
87 #define OHCI_HC_COMMAND_STATUS                              0x02
88 #define OHCI_HC_INTERRUPT_STATUS                            0x03
89 #define OHCI_HC_INTERRUPT_ENABLE                            0x04
90 #define OHCI_HC_INTERRUPT_DISABLE                           0x05
91 #define OHCI_HC_HCCA                                        0x06
92 #define OHCI_HC_PERIOD_CURRENT_ED                           0x07
93 #define OHCI_HC_CONTROL_HEAD_ED                             0x08
94 #define OHCI_HC_CONTROL_CURRENT_ED                          0x09
95 #define OHCI_HC_BULK_HEAD_ED                                0x0a
96 #define OHCI_HC_BULK_CURRENT_ED                             0x0b
97 #define OHCI_HC_DONE_HEAD                                   0x0c
98 #define OHCI_HC_FM_INTERVAL                                 0x0d
99 #define OHCI_HC_FM_REMAINING                                0x0e
100 #define OHCI_HC_FM_NUMBER                                   0x0f
101 #define OHCI_HC_PERIODIC_START                              0x10
102 #define OHCI_HC_LS_THRESHOLD                                0x11
103 #define OHCI_HC_RH_DESCRIPTOR_A                             0x12
104 #define OHCI_HC_RH_DESCRIPTOR_B                             0x13
105 #define OHCI_HC_RH_STATUS                                   0x14
106 #define OHCI_HC_RH_PORT_STATUS                              0x15
107 
108 
109 /* Define OHCI control register values.  */
110 
111 #define OHCI_HC_CR_CBSR_0                                   0x00000000u
112 #define OHCI_HC_CR_CBSR_1                                   0x00000001u
113 #define OHCI_HC_CR_CBSR_2                                   0x00000002u
114 #define OHCI_HC_CR_CBSR_3                                   0x00000003u
115 #define OHCI_HC_CR_PLE                                      0x00000004u
116 #define OHCI_HC_CR_IE                                       0x00000008u
117 #define OHCI_HC_CR_CLE                                      0x00000010u
118 #define OHCI_HC_CR_BLE                                      0x00000020u
119 #define OHCI_HC_CR_RESET                                    0x00000000u
120 #define OHCI_HC_CR_RESUME                                   0x00000040u
121 #define OHCI_HC_CR_OPERATIONAL                              0x00000080u
122 #define OHCI_HC_CR_SUSPEND                                  0x000000c0u
123 #define OHCI_HC_CR_IR                                       0x00000100u
124 #define OHCI_HC_CR_RWC                                      0x00000200u
125 #define OHCI_HC_CR_RWE                                      0x00000400u
126 
127 #define OHCI_HC_CONTROL_VALUE                               (OHCI_HC_CR_CBSR_3 | OHCI_HC_CR_OPERATIONAL | OHCI_HC_CR_PLE | OHCI_HC_CR_IE | OHCI_HC_CR_CLE | OHCI_HC_CR_BLE)
128 
129 
130 /* Define OHCI HCOR command/status bitmaps.  */
131 
132 #define OHCI_HC_CS_HCR                                      0x00000001u
133 #define OHCI_HC_CS_CLF                                      0x00000002u
134 #define OHCI_HC_CS_BLF                                      0x00000004u
135 
136 
137 #define OHCI_HC_RH_PSM                                      0x00000100u
138 #define OHCI_HC_RH_NPS                                      0x00000200u
139 #define OHCI_HC_RH_DT                                       0x00000400u
140 #define OHCI_HC_RH_OCPM                                     0x00000800u
141 #define OHCI_HC_RH_NOCP                                     0x00001000u
142 #define OHCI_HC_RH_POTPGT                                   24u
143 
144 #define OHCI_HC_RS_LPS                                      0x00000001u
145 #define OHCI_HC_RS_OCI                                      0x00000002u
146 #define OHCI_HC_RS_DRWE                                     0x00008000u
147 #define OHCI_HC_RS_LPSC                                     0x00010000u
148 #define OHCI_HC_RS_OCIC                                     0x00020000u
149 #define OHCI_HC_RS_CRWE                                     0x80000000u
150 
151 #define OHCI_HC_PS_CCS                                      0x00000001u
152 #define OHCI_HC_PS_CPE                                      0x00000001u
153 #define OHCI_HC_PS_PES                                      0x00000002u
154 #define OHCI_HC_PS_PSS                                      0x00000004u
155 #define OHCI_HC_PS_POCI                                     0x00000008u
156 #define OHCI_HC_PS_PRS                                      0x00000010u
157 #define OHCI_HC_PS_PPS                                      0x00000100u
158 #define OHCI_HC_PS_LSDA                                     0x00000200u
159 #define OHCI_HC_PS_CSC                                      0x00010000u
160 #define OHCI_HC_PS_PESC                                     0x00020000u
161 #define OHCI_HC_PS_PSSC                                     0x00040000u
162 #define OHCI_HC_PS_OCIC                                     0x00080000u
163 #define OHCI_HC_PS_PRSC                                     0x00100000u
164 
165 
166 /* Define OHCI interrupt status register definitions.  */
167 
168 #define OHCI_HC_INT_SO                                      0x00000001u
169 #define OHCI_HC_INT_WDH                                     0x00000002u
170 #define OHCI_HC_INT_SF                                      0x00000004u
171 #define OHCI_HC_INT_RD                                      0x00000008u
172 #define OHCI_HC_INT_UE                                      0x00000010u
173 #define OHCI_HC_INT_FNO                                     0x00000020u
174 #define OHCI_HC_INT_RHSC                                    0x00000040u
175 #define OHCI_HC_INT_OC                                      0x40000000u
176 
177 #define OHCI_HC_INT_MIE                                     0x80000000u
178 
179 
180 #define OHCI_HC_INTERRUPT_ENABLE_NORMAL                     (OHCI_HC_INT_WDH | OHCI_HC_INT_RD | OHCI_HC_INT_UE | OHCI_HC_INT_RHSC | OHCI_HC_INT_MIE)
181 
182 #define OHCI_HC_INTERRUPT_DISABLE_ALL                       (OHCI_HC_INT_SO   |  \
183                                                             OHCI_HC_INT_WDH  |  \
184                                                             OHCI_HC_INT_SF   |  \
185                                                             OHCI_HC_INT_RD   |  \
186                                                             OHCI_HC_INT_UE   |  \
187                                                             OHCI_HC_INT_FNO  |  \
188                                                             OHCI_HC_INT_RHSC |  \
189                                                             OHCI_HC_INT_OC   |  \
190                                                             OHCI_HC_INT_MIE)
191 
192 
193 /* Define OHCI frame interval definition. */
194 
195 #define OHCI_HC_FM_INTERVAL_CLEAR                           0x8000ffffu
196 #define OHCI_HC_FM_INTERVAL_SET                             0x27780000u
197 #define OHCI_HC_FM_INTERVAL_FI_MASK                         0x00003fffu
198 
199 
200 /* Define OHCI static definition.  */
201 
202 #define UX_OHCI_AVAILABLE_BANDWIDTH                         6000u
203 #define UX_OHCI_INIT_DELAY                                  1000
204 #define UX_OHCI_RESET_RETRY                                 1000
205 #define UX_OHCI_RESET_DELAY                                 10
206 #define UX_OHCI_PORT_RESET_RETRY                            10
207 #define UX_OHCI_PORT_RESET_DELAY                            10
208 
209 
210 /* Define OHCI initialization values.  */
211 
212 #define UX_OHCI_COMMAND_STATUS_RESET                        0
213 #define UX_OHCI_INIT_RESET_DELAY                            10
214 
215 /* Define OHCI completion code errors.  */
216 
217 #define UX_OHCI_NO_ERROR                                    0x00
218 #define UX_OHCI_ERROR_CRC                                   0x01
219 #define UX_OHCI_ERROR_BIT_STUFFING                          0x02
220 #define UX_OHCI_ERROR_DATA_TOGGLE                           0x03
221 #define UX_OHCI_ERROR_STALL                                 0x04
222 #define UX_OHCI_ERROR_DEVICE_NOT_RESPONDING                 0x05
223 #define UX_OHCI_ERROR_PID_FAILURE                           0x06
224 #define UX_OHCI_ERROR_PID_UNEXPECTED                        0x07
225 #define UX_OHCI_ERROR_DATA_OVERRRUN                         0x08
226 #define UX_OHCI_ERROR_DATA_UNDERRUN                         0x09
227 #define UX_OHCI_ERROR_BUFFER_OVERRRUN                       0x0c
228 #define UX_OHCI_ERROR_BUFFER_UNDERRUN                       0x0d
229 #define UX_OHCI_NOT_ACCESSED                                0x0e
230 
231 #define UX_OHCI_PRSC_EVENT                                  0x1u
232 
233 #define UX_OHCI_PRSC_EVENT_TIMEOUT                          100
234 
235 /* Define OHCI HCCA structure.  */
236 
237 typedef struct UX_HCD_OHCI_HCCA_STRUCT
238 {
239 
240     struct UX_OHCI_ED_STRUCT
241                     *ux_hcd_ohci_hcca_ed[32];
242     USHORT          ux_hcd_ohci_hcca_frame_number;
243     USHORT          ux_hcd_ohci_hcca_reserved1;
244     struct UX_OHCI_TD_STRUCT
245                     *ux_hcd_ohci_hcca_done_head;
246     UCHAR           ux_hcd_ohci_hcca_reserved2[116];
247 } UX_HCD_OHCI_HCCA;
248 
249 
250 /* Define OHCI HCD structure.  */
251 
252 typedef struct UX_HCD_OHCI_STRUCT
253 {
254 
255     struct UX_HCD_STRUCT
256                     *ux_hcd_ohci_hcd_owner;
257     struct UX_HCD_OHCI_HCCA_STRUCT
258                     *ux_hcd_ohci_hcca;
259     ULONG           *ux_hcd_ohci_hcor;
260     UINT            ux_hcd_ohci_nb_root_hubs;
261     struct UX_OHCI_TD_STRUCT
262                     *ux_hcd_ohci_done_head;
263     struct UX_OHCI_ED_STRUCT
264                     *ux_hcd_ohci_ed_list;
265     struct UX_OHCI_TD_STRUCT
266                     *ux_hcd_ohci_td_list;
267     struct UX_OHCI_ISO_TD_STRUCT
268                     *ux_hcd_ohci_iso_td_list;
269     UX_EVENT_FLAGS_GROUP
270                     ux_hcd_ohci_event_flags_group;
271 } UX_HCD_OHCI;
272 
273 
274 /* Define OHCI ED structure.  */
275 
276 typedef struct UX_OHCI_ED_STRUCT
277 {
278 
279     ULONG           ux_ohci_ed_dw0;
280     struct UX_OHCI_TD_STRUCT
281                     *ux_ohci_ed_tail_td;
282     struct UX_OHCI_TD_STRUCT
283                     *ux_ohci_ed_head_td;
284     struct UX_OHCI_ED_STRUCT
285                     *ux_ohci_ed_next_ed;
286     struct UX_OHCI_ED_STRUCT
287                     *ux_ohci_ed_previous_ed;
288     ULONG           ux_ohci_ed_status;
289     struct UX_ENDPOINT_STRUCT
290                     *ux_ohci_ed_endpoint;
291     ULONG           ux_ohci_ed_frame;
292 } UX_OHCI_ED;
293 
294 
295 /* Define OHCI ED bitmap.  */
296 
297 #define UX_OHCI_ED_LOW_SPEED                                0x00002000u
298 #define UX_OHCI_ED_SKIP                                     0x00004000u
299 #define UX_OHCI_ED_ISOCHRONOUS                              0x00008000u
300 #define UX_OHCI_ED_MPS                                      0x0000ffffu
301 
302 #define UX_OHCI_ED_HALTED                                   0x00000001u
303 #define UX_OHCI_ED_TOGGLE_CARRY                             0x00000002u
304 #define UX_OHCI_ED_MASK_TD                                  (~0x00000003u)
305 
306 #define UX_OHCI_ED_OUT                                      0x0800u
307 #define UX_OHCI_ED_IN                                       0x1000u
308 
309 
310 /* Define OHCI TD structure.  */
311 
312 typedef struct UX_OHCI_TD_STRUCT
313 {
314     ULONG           ux_ohci_td_dw0;
315     UCHAR *         ux_ohci_td_cbp;
316     struct UX_OHCI_TD_STRUCT
317                     *ux_ohci_td_next_td;
318     UCHAR *         ux_ohci_td_be;
319     ULONG           ux_ohci_td_reserved_1[4];
320     struct UX_TRANSFER_STRUCT
321                     *ux_ohci_td_transfer_request;
322     struct UX_OHCI_TD_STRUCT
323                     *ux_ohci_td_next_td_transfer_request;
324     struct UX_OHCI_ED_STRUCT
325                     *ux_ohci_td_ed;
326     ULONG           ux_ohci_td_length;
327     ULONG           ux_ohci_td_status;
328     ULONG           ux_ohci_td_reserved_2[3];
329 } UX_OHCI_TD;
330 
331 
332 /* Define OHCI TD bitmap.  */
333 
334 #define UX_OHCI_TD_OUT                                      0x00080000u
335 #define UX_OHCI_TD_IN                                       0x00100000u
336 #define UX_OHCI_TD_DEFAULT_DW0                              0xf0000000u
337 #define UX_OHCI_TD_DATA0                                    0x02000000u
338 #define UX_OHCI_TD_DATA1                                    0x03000000u
339 #define UX_OHCI_TD_R                                        0x00040000u
340 
341 #define UX_OHCI_TD_SETUP_PHASE                              0x00010000u
342 #define UX_OHCI_TD_DATA_PHASE                               0x00020000u
343 #define UX_OHCI_TD_STATUS_PHASE                             0x00040000u
344 #define UX_OHCI_TD_CC                                       28u
345 
346 
347 /* Define OHCI ISOCHRONOUS TD structure.  */
348 
349 typedef struct UX_OHCI_ISO_TD_STRUCT
350 {
351 
352     ULONG           ux_ohci_iso_td_dw0;
353     UCHAR *         ux_ohci_iso_td_bp0;
354     struct UX_OHCI_TD_STRUCT
355                     *ux_ohci_iso_td_next_td;
356     UCHAR *         ux_ohci_iso_td_be;
357     USHORT          ux_ohci_iso_td_offset_psw[8];
358     struct UX_TRANSFER_STRUCT
359                     *ux_ohci_iso_td_transfer_request;
360     struct UX_OHCI_TD_STRUCT
361                     *ux_ohci_iso_td_next_td_transfer_request;
362     struct UX_OHCI_ED_STRUCT
363                     *ux_ohci_iso_td_ed;
364     ULONG           ux_ohci_iso_td_length;
365     ULONG           ux_ohci_iso_td_status;
366     ULONG           ux_ohci_iso_td_reserved[3];
367 } UX_OHCI_ISO_TD;
368 
369 
370 /* Define OHCI ISOCHRONOUS TD bitmap.  */
371 
372 #define UX_OHCI_ISO_TD_BASE                                 0xfffff000u
373 #define UX_OHCI_ISO_TD_OFFSET                               0x00000fffu
374 #define UX_OHCI_ISO_TD_PSW_CC                               0x0000e000u
375 #define UX_OHCI_ISO_TD_FC                                   24u
376 
377 
378 /* Define OHCI function prototypes.  */
379 
380 UINT    _ux_hcd_ohci_asynchronous_endpoint_create(UX_HCD_OHCI *hcd_ohci, UX_ENDPOINT *endpoint);
381 UINT    _ux_hcd_ohci_asynchronous_endpoint_destroy(UX_HCD_OHCI *hcd_ohci, UX_ENDPOINT *endpoint);
382 UINT    _ux_hcd_ohci_controller_disable(UX_HCD_OHCI *hcd_ohci);
383 VOID    _ux_hcd_ohci_done_queue_process(UX_HCD_OHCI *hcd_ohci);
384 UX_OHCI_ED  *_ux_hcd_ohci_ed_obtain(UX_HCD_OHCI *hcd_ohci);
385 UINT    _ux_hcd_ohci_endpoint_error_clear(UX_HCD_OHCI *hcd_ohci, UX_ENDPOINT *endpoint);
386 UINT    _ux_hcd_ohci_endpoint_reset(UX_HCD_OHCI *hcd_ohci, UX_ENDPOINT *endpoint);
387 UINT    _ux_hcd_ohci_entry(UX_HCD *hcd, UINT function, VOID *parameter);
388 UINT    _ux_hcd_ohci_frame_number_get(UX_HCD_OHCI *hcd_ohci, ULONG *frame_number);
389 VOID    _ux_hcd_ohci_frame_number_set(UX_HCD_OHCI *hcd_ohci, ULONG frame_number);
390 UINT    _ux_hcd_ohci_initialize(UX_HCD *hcd);
391 UINT    _ux_hcd_ohci_interrupt_endpoint_create(UX_HCD_OHCI *hcd_ohci, UX_ENDPOINT *endpoint);
392 VOID    _ux_hcd_ohci_interrupt_handler(VOID);
393 UINT    _ux_hcd_ohci_isochronous_endpoint_create(UX_HCD_OHCI *hcd_ohci, UX_ENDPOINT *endpoint);
394 UX_OHCI_ISO_TD  *_ux_hcd_ohci_isochronous_td_obtain(UX_HCD_OHCI *hcd_ohci);
395 UX_OHCI_ED  *_ux_hcd_ohci_least_traffic_list_get(UX_HCD_OHCI *hcd_ohci);
396 VOID    _ux_hcd_ohci_next_td_clean(UX_OHCI_TD *td);
397 UINT    _ux_hcd_ohci_periodic_endpoint_destroy(UX_HCD_OHCI *hcd_ohci, UX_ENDPOINT *endpoint);
398 UINT    _ux_hcd_ohci_periodic_tree_create(UX_HCD_OHCI *hcd_ohci);
399 UINT    _ux_hcd_ohci_port_disable(UX_HCD_OHCI *hcd_ohci, ULONG port_index);
400 UINT    _ux_hcd_ohci_port_enable(UX_HCD_OHCI *hcd_ohci, ULONG port_index);
401 UINT    _ux_hcd_ohci_port_reset(UX_HCD_OHCI *hcd_ohci, ULONG port_index);
402 UINT    _ux_hcd_ohci_port_resume(UX_HCD_OHCI *hcd_ohci, UINT port_index);
403 ULONG   _ux_hcd_ohci_port_status_get(UX_HCD_OHCI *hcd_ohci, ULONG port_index);
404 UINT    _ux_hcd_ohci_port_suspend(UX_HCD_OHCI *hcd_ohci, ULONG port_index);
405 UINT    _ux_hcd_ohci_power_down_port(UX_HCD_OHCI *hcd_ohci, ULONG port_index);
406 UINT    _ux_hcd_ohci_power_on_port(UX_HCD_OHCI *hcd_ohci, ULONG port_index);
407 VOID    _ux_hcd_ohci_power_root_hubs(UX_HCD_OHCI *hcd_ohci);
408 ULONG   _ux_hcd_ohci_register_read(UX_HCD_OHCI *hcd_ohci, ULONG ohci_register);
409 VOID    _ux_hcd_ohci_register_write(UX_HCD_OHCI *hcd_ohci, ULONG ohci_register, ULONG value);
410 UX_OHCI_TD  *_ux_hcd_ohci_regular_td_obtain(UX_HCD_OHCI *hcd_ohci);
411 UINT    _ux_hcd_ohci_request_bulk_transfer(UX_HCD_OHCI *hcd_ohci, UX_TRANSFER *transfer_request);
412 UINT    _ux_hcd_ohci_request_control_transfer(UX_HCD_OHCI *hcd_ohci, UX_TRANSFER *transfer_request);
413 UINT    _ux_hcd_ohci_request_interrupt_transfer(UX_HCD_OHCI *hcd_ohci, UX_TRANSFER *transfer_request);
414 UINT    _ux_hcd_ohci_request_isochronous_transfer(UX_HCD_OHCI *hcd_ohci, UX_TRANSFER *transfer_request);
415 UINT    _ux_hcd_ohci_request_transfer(UX_HCD_OHCI *hcd_ohci, UX_TRANSFER *transfer_request);
416 UINT    _ux_hcd_ohci_transfer_abort(UX_HCD_OHCI *hcd_ohci, UX_TRANSFER *transfer_request);
417 VOID    _ux_hcd_ohci_transfer_request_process(UX_TRANSFER *transfer_request);
418 
419 #define ux_hcd_ohci_initialize                      _ux_hcd_ohci_initialize
420 #define ux_hcd_ohci_interrupt_handler               _ux_hcd_ohci_interrupt_handler
421 
422 /* Determine if a C++ compiler is being used.  If so, complete the standard
423    C conditional started above.  */
424 #ifdef __cplusplus
425 }
426 #endif
427 
428 #endif
429 
430