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