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