From 53114c0f16527bb6fd076e133cefde195697d5f3 Mon Sep 17 00:00:00 2001 From: sakumisu <1203593632@qq.com> Date: Thu, 4 Jul 2024 21:35:59 +0800 Subject: [PATCH] refactor(e(o)hci): rename usb_hc_e(o)hci to usb_e(o)hci_reg, usb_hc_e(o)hci_priv to usb_hc_e(o)hci --- port/ehci/usb_ehci_priv.h | 84 ------- port/ehci/usb_ehci_reg.h | 393 ++++++++++++++++++++++++++++++ port/ehci/usb_glue_aic.c | 2 +- port/ehci/usb_hc_ehci.c | 4 +- port/ehci/usb_hc_ehci.h | 431 ++++++--------------------------- port/ohci/usb_hc_ohci.c | 4 +- port/ohci/usb_hc_ohci.h | 494 ++------------------------------------ port/ohci/usb_ohci_priv.h | 24 -- port/ohci/usb_ohci_reg.h | 484 +++++++++++++++++++++++++++++++++++++ 9 files changed, 969 insertions(+), 951 deletions(-) delete mode 100644 port/ehci/usb_ehci_priv.h create mode 100644 port/ehci/usb_ehci_reg.h delete mode 100644 port/ohci/usb_ohci_priv.h create mode 100644 port/ohci/usb_ohci_reg.h diff --git a/port/ehci/usb_ehci_priv.h b/port/ehci/usb_ehci_priv.h deleted file mode 100644 index ba1d3510..00000000 --- a/port/ehci/usb_ehci_priv.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2022, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef _USB_EHCI_PRIV_H -#define _USB_EHCI_PRIV_H - -#include "usbh_core.h" -#include "usbh_hub.h" -#include "usb_hc_ehci.h" - -#define EHCI_HCCR ((struct ehci_hccr *)(uintptr_t)(bus->hcd.reg_base + CONFIG_USB_EHCI_HCCR_OFFSET)) -#define EHCI_HCOR ((struct ehci_hcor *)(uintptr_t)(bus->hcd.reg_base + CONFIG_USB_EHCI_HCCR_OFFSET + g_ehci_hcd[bus->hcd.hcd_id].hcor_offset)) - -#define EHCI_PTR2ADDR(x) ((uint32_t)(uintptr_t)(x) & ~0x1F) -#define EHCI_ADDR2QH(x) ((struct ehci_qh_hw *)(uintptr_t)((uint32_t)(x) & ~0x1F)) -#define EHCI_ADDR2QTD(x) ((struct ehci_qtd_hw *)(uintptr_t)((uint32_t)(x) & ~0x1F)) -#define EHCI_ADDR2ITD(x) ((struct ehci_itd_hw *)(uintptr_t)((uint32_t)(x) & ~0x1F)) - -#ifndef CONFIG_USB_EHCI_QH_NUM -#define CONFIG_USB_EHCI_QH_NUM CONFIG_USBHOST_PIPE_NUM -#endif -#ifndef CONFIG_USB_EHCI_QTD_NUM -#define CONFIG_USB_EHCI_QTD_NUM 3 -#endif -#ifndef CONFIG_USB_EHCI_ITD_NUM -#define CONFIG_USB_EHCI_ITD_NUM 5 -#endif -#ifndef CONFIG_USB_EHCI_ISO_NUM -#define CONFIG_USB_EHCI_ISO_NUM 4 -#endif - -extern uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port); - -struct ehci_qtd_hw { - struct ehci_qtd hw; - struct usbh_urb *urb; - uint32_t length; -} __attribute__((aligned(32))); - -struct ehci_qh_hw { - struct ehci_qh hw; - struct ehci_qtd_hw qtd_pool[CONFIG_USB_EHCI_QTD_NUM]; - uint32_t first_qtd; - struct usbh_urb *urb; - usb_osal_sem_t waitsem; - uint8_t remove_in_iaad; -} __attribute__((aligned(32))); - -struct ehci_itd_hw { - struct ehci_itd hw; - struct usbh_urb *urb; - uint16_t start_frame; - uint8_t mf_unmask; - uint8_t mf_valid; - uint32_t pkt_idx[8]; -} __attribute__((aligned(32))); - -struct ehci_iso_hw -{ - struct ehci_itd_hw itd_pool[CONFIG_USB_EHCI_ITD_NUM]; - uint32_t itd_num; -}; - -struct ehci_hcd { - bool ehci_qh_used[CONFIG_USB_EHCI_QH_NUM]; - bool ehci_iso_used[CONFIG_USB_EHCI_ISO_NUM]; - bool ppc; /* Port Power Control */ - bool has_tt; /* if use tt instead of Companion Controller */ - uint8_t n_cc; /* Number of Companion Controller */ - uint8_t n_pcc; /* Number of ports supported per companion host controller */ - uint8_t n_ports; - uint8_t hcor_offset; -}; - -extern struct ehci_hcd g_ehci_hcd[CONFIG_USBHOST_MAX_BUS]; -extern uint32_t g_framelist[CONFIG_USBHOST_MAX_BUS][USB_ALIGN_UP(CONFIG_USB_EHCI_FRAME_LIST_SIZE, 1024)]; - -int ehci_iso_urb_init(struct usbh_bus *bus, struct usbh_urb *urb); -void ehci_kill_iso_urb(struct usbh_bus *bus, struct usbh_urb *urb); -void ehci_scan_isochronous_list(struct usbh_bus *bus); - -#endif diff --git a/port/ehci/usb_ehci_reg.h b/port/ehci/usb_ehci_reg.h new file mode 100644 index 00000000..741eef64 --- /dev/null +++ b/port/ehci/usb_ehci_reg.h @@ -0,0 +1,393 @@ +/**************************************************************************** + * include/nuttx/usb/ehci.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ +/* + * Copyright 2022 sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __INCLUDE_NUTTX_USB_EHCI_H +#define __INCLUDE_NUTTX_USB_EHCI_H + +#define EHCI_FULL_SPEED (0) /* Full-Speed (12Mbs) */ +#define EHCI_LOW_SPEED (1) /* Low-Speed (1.5Mbs) */ +#define EHCI_HIGH_SPEED (2) /* High-Speed (480 Mb/s) */ + +/* Host Controller Capability Register Bit Definitions **********************/ + +/* Structural Parameters. Paragraph 2.2.3 */ + +#define EHCI_HCSPARAMS_NPORTS_SHIFT (0) /* Bit 0-3: Number of physical downstream ports */ +#define EHCI_HCSPARAMS_NPORTS_MASK (15 << EHCI_HCSPARAMS_NPORTS_SHIFT) +#define EHCI_HCSPARAMS_PPC (1 << 4) /* Bit 4: Port Power Control */ +#define EHCI_HCSPARAMS_PRR (1 << 7) /* Bit 7: Port Routing Rules */ +#define EHCI_HCSPARAMS_NPCC_SHIFT (8) /* Bit 8-11: Number of Ports per Companion Controller */ +#define EHCI_HCSPARAMS_NPCC_MASK (15 << EHCI_HCSPARAMS_NPCC_SHIFT) +#define EHCI_HCSPARAMS_NCC_SHIFT (12) /* Bit 12-15: Number of Companion Controllers */ +#define EHCI_HCSPARAMS_NCC_MASK (15 << EHCI_HCSPARAMS_NCC_SHIFT) +#define EHCI_HCSPARAMS_PIND (1 << 16) /* Bit 16: Port Indicators */ +#define EHCI_HCSPARAMS_DBGPORT_SHIFT (20) /* Bit 20-23: Debug Port Number */ +#define EHCI_HCSPARAMS_DBGPORT_MASK (15 << EHCI_HCSPARAMS_DBGPORT_SHIFT) + +/* Capability Parameters. Paragraph 2.2.4 */ + +#define EHCI_HCCPARAMS_64BIT (1 << 0) /* Bit 0: 64-bit Addressing Capability */ +#define EHCI_HCCPARAMS_PFLF (1 << 1) /* Bit 1: Programmable Frame List Flag */ +#define EHCI_HCCPARAMS_ASPC (1 << 2) /* Bit 2: Asynchronous Schedule Park Capability */ +#define EHCI_HCCPARAMS_IST_SHIFT (4) /* Bits 4-7: Isochronous Scheduling Threshold */ +#define EHCI_HCCPARAMS_IST_MASK (15 << EHCI_HCCPARAMS_IST_SHIFT) +#define EHCI_HCCPARAMS_EECP_SHIFT (8) /* Bits 8-15: EHCI Extended Capabilities Pointer */ +#define EHCI_HCCPARAMS_EECP_MASK (0xff << EHCI_HCCPARAMS_EECP_SHIFT) + +/* Host Controller Operational Register Bit Definitions *********************/ + +/* USB Command. Paragraph 2.3.1 */ + +#define EHCI_USBCMD_RUN (1 << 0) /* Bit 0: Run/Stop */ +#define EHCI_USBCMD_HCRESET (1 << 1) /* Bit 1: Host Controller Reset */ +#define EHCI_USBCMD_FLSIZE_SHIFT (2) /* Bits 2-3: Frame List Size */ +#define EHCI_USBCMD_FLSIZE_MASK (3 << EHCI_USBCMD_FLSIZE_SHIFT) +#define EHCI_USBCMD_FLSIZE_1024 (0 << EHCI_USBCMD_FLSIZE_SHIFT) /* 1024 elements (4096 bytes) */ +#define EHCI_USBCMD_FLSIZE_512 (1 << EHCI_USBCMD_FLSIZE_SHIFT) /* 512 elements (2048 bytes) */ +#define EHCI_USBCMD_FLSIZE_256 (2 << EHCI_USBCMD_FLSIZE_SHIFT) /* 256 elements (1024 bytes) */ +#define EHCI_USBCMD_PSEN (1 << 4) /* Bit 4: Periodic Schedule Enable */ +#define EHCI_USBCMD_ASEN (1 << 5) /* Bit 5: Asynchronous Schedule Enable */ +#define EHCI_USBCMD_IAAD (1 << 6) /* Bit 6: Interrupt on Async Advance Doorbell */ +#define EHCI_USBCMD_LRESET (1 << 7) /* Bit 7: Light Host Controller Reset */ +#define EHCI_USBCMD_ASYNC_PARKCNT_SHIFT (8) /* Bits 8-9: Asynchronous Schedule Park Mode Count */ +#define EHCI_USBCMD_ASYNC_PARKCNT_MASK (3 << EHCI_USBCMD_ASYNC_PARKCNT_SHIFT) +#define EHCI_USBCMD_ASYNC_PARK (1 << 11) /* Bit 11: Asynchronous Schedule Park Mode Enable */ +#define EHCI_USBCMD_ITHRE_SHIFT (16) /* Bits 16-23: Interrupt Threshold Control */ +#define EHCI_USBCMD_ITHRE_MASK (0xff << EHCI_USBCMD_ITHRE_SHIFT) +#define EHCI_USBCMD_ITHRE_1MF (0x01 << EHCI_USBCMD_ITHRE_SHIFT) /* 1 micro-frame */ +#define EHCI_USBCMD_ITHRE_2MF (0x02 << EHCI_USBCMD_ITHRE_SHIFT) /* 2 micro-frames */ +#define EHCI_USBCMD_ITHRE_4MF (0x04 << EHCI_USBCMD_ITHRE_SHIFT) /* 4 micro-frames */ +#define EHCI_USBCMD_ITHRE_8MF (0x08 << EHCI_USBCMD_ITHRE_SHIFT) /* 8 micro-frames (default, 1 ms) */ +#define EHCI_USBCMD_ITHRE_16MF (0x10 << EHCI_USBCMD_ITHRE_SHIFT) /* 16 micro-frames (2 ms) */ +#define EHCI_USBCMD_ITHRE_32MF (0x20 << EHCI_USBCMD_ITHRE_SHIFT) /* 32 micro-frames (4 ms) */ +#define EHCI_USBCMD_ITHRE_64MF (0x40 << EHCI_USBCMD_ITHRE_SHIFT) /* 64 micro-frames (8 ms) */ + +/* USB Status. Paragraph 2.3.2 */ + +#define EHCI_USBSTS_INT (1 << 0) /* Bit 0: USB Interrupt */ +#define EHCI_USBSTS_ERR (1 << 1) /* Bit 1: USB Error Interrupt */ +#define EHCI_USBSTS_PCD (1 << 2) /* Bit 2: Port Change Detect */ +#define EHCI_USBSTS_FLR (1 << 3) /* Bit 3: Frame List Rollover */ +#define EHCI_USBSTS_FATAL (1 << 4) /* Bit 4: Host System Error */ +#define EHCI_USBSTS_IAA (1 << 5) /* Bit 5: Interrupt on Async Advance */ +#define EHCI_USBSTS_HALTED (1 << 12) /* Bit 12: HC Halted */ +#define EHCI_USBSTS_RECLAM (1 << 13) /* Bit 13: Reclamation */ +#define EHCI_USBSTS_PSS (1 << 14) /* Bit 14: Periodic Schedule Status */ +#define EHCI_USBSTS_ASS (1 << 15) /* Bit 15: Asynchronous Schedule Status */ + /* Bits 16-31: Reserved */ + +/* USB Interrupt Enable. Paragraph 2.3.3 */ + +#define EHCI_USBIE_INT (1 << 0) /* Bit 0: USB Interrupt */ +#define EHCI_USBIE_ERR (1 << 1) /* Bit 1: USB Error Interrupt */ +#define EHCI_USBIE_PCD (1 << 2) /* Bit 2: Port Change Detect */ +#define EHCI_USBIE_FLROLL (1 << 3) /* Bit 3: Frame List Rollover */ +#define EHCI_USBIE_FATAL (1 << 4) /* Bit 4: Host System Error */ +#define EHCI_USBIE_IAA (1 << 5) /* Bit 5: Interrupt on Async Advance */ +#define EHCI_USBIE_ALLINTS (0x3f) /* Bits 0-5: All interrupts */ + +/* USB Frame Index. Paragraph 2.3.4 */ + +#define EHCI_FRINDEX_MASK (0x3fff) /* Bits 0-13: Frame index */ + +/* 4G Segment Selector. + * Paragraph 2.3.5, Bits[64:32] of data structure addresses + */ + +/* Frame List Base Address. Paragraph 2.3.6 */ +#define EHCI_PERIODICLISTBASE_MASK (0xfffff000) /* Bits 12-31: Base Address (Low) */ + +/* Next Asynchronous List Address. Paragraph 2.3.7 */ + +#define EHCI_ASYNCLISTADDR_MASK (0xffffffe0) /* Bits 5-31: Link Pointer Low (LPL) */ + +/* Configured Flag Register. Paragraph 2.3.8 */ + +#define EHCI_CONFIGFLAG (1 << 0) /* Bit 0: Configure Flag */ + +/* Port Status/Control, Port 1-n. Paragraph 2.3.9 */ + +#define EHCI_PORTSC_CCS (1 << 0) /* Bit 0: Current Connect Status */ +#define EHCI_PORTSC_CSC (1 << 1) /* Bit 1: Connect Status Change */ +#define EHCI_PORTSC_PE (1 << 2) /* Bit 2: Port Enable */ +#define EHCI_PORTSC_PEC (1 << 3) /* Bit 3: Port Enable/Disable Change */ +#define EHCI_PORTSC_OCA (1 << 4) /* Bit 4: Over-current Active */ +#define EHCI_PORTSC_OCC (1 << 5) /* Bit 5: Over-current Change */ +#define EHCI_PORTSC_RESUME (1 << 6) /* Bit 6: Force Port Resume */ +#define EHCI_PORTSC_SUSPEND (1 << 7) /* Bit 7: Suspend */ +#define EHCI_PORTSC_RESET (1 << 8) /* Bit 8: Port Reset */ +#define EHCI_PORTSC_LSTATUS_SHIFT (10) /* Bits 10-11: Line Status */ +#define EHCI_PORTSC_LSTATUS_MASK (3 << EHCI_PORTSC_LSTATUS_SHIFT) +#define EHCI_PORTSC_LSTATUS_SE0 (0 << EHCI_PORTSC_LSTATUS_SHIFT) /* SE0 Not Low-speed device, perform EHCI reset */ +#define EHCI_PORTSC_LSTATUS_KSTATE (1 << EHCI_PORTSC_LSTATUS_SHIFT) /* K-state Low-speed device, release ownership of port */ +#define EHCI_PORTSC_LSTATUS_JSTATE (2 << EHCI_PORTSC_LSTATUS_SHIFT) /* J-state Not Low-speed device, perform EHCI reset */ +#define EHCI_PORTSC_PP (1 << 12) /* Bit 12: Port Power */ +#define EHCI_PORTSC_OWNER (1 << 13) /* Bit 13: Port Owner */ +#define EHCI_PORTSC_PIC_SHIFT (14) /* Bits 14-15: Port Indicator Control */ +#define EHCI_PORTSC_PIC_MASK (3 << EHCI_PORTSC_PIC_SHIFT) +#define EHCI_PORTSC_PIC_OFF (0 << EHCI_PORTSC_PIC_SHIFT) /* Port indicators are off */ +#define EHCI_PORTSC_PIC_AMBER (1 << EHCI_PORTSC_PIC_SHIFT) /* Amber */ +#define EHCI_PORTSC_PIC_GREEN (2 << EHCI_PORTSC_PIC_SHIFT) /* Green */ +#define EHCI_PORTSC_PTC_SHIFT (16) /* Bits 16-19: Port Test Control */ +#define EHCI_PORTSC_PTC_MASK (15 << EHCI_PORTSC_PTC_SHIFT) +#define EHCI_PORTSC_PTC_DISABLED (0 << EHCI_PORTSC_PTC_SHIFT) /* Test mode not enabled */ +#define EHCI_PORTSC_PTC_JSTATE (1 << EHCI_PORTSC_PTC_SHIFT) /* Test J_STATE */ +#define EHCI_PORTSC_PTC_KSTATE (2 << EHCI_PORTSC_PTC_SHIFT) /* Test K_STATE */ +#define EHCI_PORTSC_PTC_SE0NAK (3 << EHCI_PORTSC_PTC_SHIFT) /* Test SE0_NAK */ +#define EHCI_PORTSC_PTC_PACKET (4 << EHCI_PORTSC_PTC_SHIFT) /* Test Packet */ +#define EHCI_PORTSC_PTC_ENABLE (5 << EHCI_PORTSC_PTC_SHIFT) /* Test FORCE_ENABLE */ +#define EHCI_PORTSC_WKCCNTE (1 << 20) /* Bit 20: Wake on Connect Enable */ +#define EHCI_PORTSC_WKDSCNNTE (1 << 21) /* Bit 21: Wake on Disconnect Enable */ +#define EHCI_PORTSC_WKOCE (1 << 22) /* Bit 22: Wake on Over-current Enable */ + /* Bits 23-31: Reserved */ + +#define EHCI_PORTSC_ALLINTS (EHCI_PORTSC_CSC | EHCI_PORTSC_PEC | \ + EHCI_PORTSC_OCC | EHCI_PORTSC_RESUME) + +/* Queue Head. Paragraph 3.6 */ + +/* Queue Head Horizontal Link Pointer: Queue Head DWord 0. Table 3-19 */ + +#define QH_HLP_END 0x1 + +#define QH_HLP_ITD(x) (((uint32_t)(x) & ~0x1F) | 0x0) /* Isochronous Transfer Descriptor */ +#define QH_HLP_QH(x) (((uint32_t)(x) & ~0x1F) | 0x2) /* Queue Head */ +#define QH_HLP_SITD(x) (((uint32_t)(x) & ~0x1F) | 0x4) /* Split Transaction Isochronous Transfer Descriptor */ +#define QH_HLP_FSTN(x) (((uint32_t)(x) & ~0x1F) | 0x6) /* Frame Span Traversal Node */ + +/* Endpoint Characteristics: Queue Head DWord 1. Table 3-19 */ + +#define QH_EPCHAR_DEVADDR_SHIFT (0) /* Bitx 0-6: Device Address */ +#define QH_EPCHAR_DEVADDR_MASK (0x7f << QH_EPCHAR_DEVADDR_SHIFT) +#define QH_EPCHAR_I (1 << 7) /* Bit 7: Inactivate on Next Transaction */ +#define QH_EPCHAR_ENDPT_SHIFT (8) /* Bitx 8-11: Endpoint Number */ +#define QH_EPCHAR_ENDPT_MASK (15 << QH_EPCHAR_ENDPT_SHIFT) +#define QH_EPCHAR_EPS_SHIFT (12) /* Bitx 12-13: Endpoint Speed */ +#define QH_EPCHAR_EPS_MASK (3 << QH_EPCHAR_EPS_SHIFT) +#define QH_EPCHAR_EPS_FULL (0 << QH_EPCHAR_EPS_SHIFT) /* Full-Speed (12Mbs) */ +#define QH_EPCHAR_EPS_LOW (1 << QH_EPCHAR_EPS_SHIFT) /* Low-Speed (1.5Mbs) */ +#define QH_EPCHAR_EPS_HIGH (2 << QH_EPCHAR_EPS_SHIFT) /* High-Speed (480 Mb/s) */ +#define QH_EPCHAR_DTC (1 << 14) /* Bit 14: Data Toggle Control */ +#define QH_EPCHAR_H (1 << 15) /* Bit 15: Head of Reclamation List Flag */ +#define QH_EPCHAR_MAXPKT_SHIFT (16) /* Bitx 16-26: Maximum Packet Length */ +#define QH_EPCHAR_MAXPKT_MASK (0x7ff << QH_EPCHAR_MAXPKT_SHIFT) +#define QH_EPCHAR_C (1 << 27) /* Bit 27: Control Endpoint Flag */ +#define QH_EPCHAR_RL_SHIFT (28) /* Bitx 28-31: Nak Count Reload */ +#define QH_EPCHAR_RL_MASK (15 << QH_EPCHAR_RL_SHIFT) + +/* Endpoint Capabilities: Queue Head DWord 2. Table 3-20 */ + +#define QH_EPCAPS_SSMASK_SHIFT (0) /* Bitx 0-7: Interrupt Schedule Mask (Frame S-mask) */ +#define QH_EPCAPS_SSMASK_MASK (0xff << QH_EPCAPS_SSMASK_SHIFT) +#define QH_EPCAPS_SSMASK(n) ((n) << QH_EPCAPS_SSMASK_SHIFT) +#define QH_EPCAPS_SCMASK_SHIFT (8) /* Bitx 8-15: Split Completion Mask (Frame C-Mask) */ +#define QH_EPCAPS_SCMASK_MASK (0xff << QH_EPCAPS_SCMASK_SHIFT) +#define QH_EPCAPS_SCMASK(n) ((n) << QH_EPCAPS_SCMASK_SHIFT) +#define QH_EPCAPS_HUBADDR_SHIFT (16) /* Bitx 16-22: Hub Address */ +#define QH_EPCAPS_HUBADDR_MASK (0x7f << QH_EPCAPS_HUBADDR_SHIFT) +#define QH_EPCAPS_HUBADDR(n) ((n) << QH_EPCAPS_HUBADDR_SHIFT) +#define QH_EPCAPS_PORT_SHIFT (23) /* Bit 23-29: Port Number */ +#define QH_EPCAPS_PORT_MASK (0x7f << QH_EPCAPS_PORT_SHIFT) +#define QH_EPCAPS_PORT(n) ((n) << QH_EPCAPS_PORT_SHIFT) +#define QH_EPCAPS_MULT_SHIFT (30) /* Bit 30-31: High-Bandwidth Pipe Multiplier */ +#define QH_EPCAPS_MULT_MASK (3 << QH_EPCAPS_MULT_SHIFT) +#define QH_EPCAPS_MULT(n) ((n) << QH_EPCAPS_MULT_SHIFT) + +/* qTD Token. Paragraph 3.5.3 */ + +#define QTD_LIST_END 1 + +#define QTD_TOKEN_STATUS_SHIFT (0) /* Bits 0-7: Status */ +#define QTD_TOKEN_STATUS_MASK (0xff << QTD_TOKEN_STATUS_SHIFT) +#define QTD_TOKEN_STATUS_PINGSTATE (1 << 0) /* Bit 0 Ping State */ +#define QTD_TOKEN_STATUS_ERR (1 << 0) /* Bit 0 Error */ +#define QTD_TOKEN_STATUS_SPLITXSTATE (1 << 1) /* Bit 1 Split Transaction State */ +#define QTD_TOKEN_STATUS_MMF (1 << 2) /* Bit 2 Missed Micro-Frame */ +#define QTD_TOKEN_STATUS_XACTERR (1 << 3) /* Bit 3 Transaction Error */ +#define QTD_TOKEN_STATUS_BABBLE (1 << 4) /* Bit 4 Babble Detected */ +#define QTD_TOKEN_STATUS_DBERR (1 << 5) /* Bit 5 Data Buffer Error */ +#define QTD_TOKEN_STATUS_HALTED (1 << 6) /* Bit 6 Halted */ +#define QTD_TOKEN_STATUS_ACTIVE (1 << 7) /* Bit 7 Active */ +#define QTD_TOKEN_STATUS_ERRORS (0x78 << QTD_TOKEN_STATUS_SHIFT) +#define QTD_TOKEN_PID_SHIFT (8) /* Bits 8-9: PID Code */ +#define QTD_TOKEN_PID_MASK (3 << QTD_TOKEN_PID_SHIFT) +#define QTD_TOKEN_PID_OUT (0 << QTD_TOKEN_PID_SHIFT) /* OUT Token generates token (E1H) */ +#define QTD_TOKEN_PID_IN (1 << QTD_TOKEN_PID_SHIFT) /* IN Token generates token (69H) */ +#define QTD_TOKEN_PID_SETUP (2 << QTD_TOKEN_PID_SHIFT) /* SETUP Token generates token (2DH) */ +#define QTD_TOKEN_CERR_SHIFT (10) /* Bits 10-11: Error Counter */ +#define QTD_TOKEN_CERR_MASK (3 << QTD_TOKEN_CERR_SHIFT) +#define QTD_TOKEN_CPAGE_SHIFT (12) /* Bits 12-14: Current Page */ +#define QTD_TOKEN_CPAGE_MASK (7 << QTD_TOKEN_CPAGE_SHIFT) +#define QTD_TOKEN_IOC (1 << 15) /* Bit 15: Interrupt On Complete */ +#define QTD_TOKEN_NBYTES_SHIFT (16) /* Bits 16-30: Total Bytes to Transfer */ +#define QTD_TOKEN_NBYTES_MASK (0x7fff << QTD_TOKEN_NBYTES_SHIFT) +#define QTD_TOKEN_TOGGLE (1 << 31) /* Bit 31: Data Toggle */ + +/* Isochronous (High-Speed) Transfer Descriptor (iTD). Paragraph 3.3 */ + +/* iTD Next Link Pointer. Paragraph 3.3.1 */ + +#define ITD_NLP_ITD(x) (((uint32_t)(x) & ~0x1F) | 0x0) +#define ITD_NLP_QH(x) (((uint32_t)(x) & ~0x1F) | 0x2) +#define ITD_NLP_SITD(x) (((uint32_t)(x) & ~0x1F) | 0x4) +#define ITD_NLP_FSTN(x) (((uint32_t)(x) & ~0x1F) | 0x6) + +/* iTD Transaction Status and Control List. Paragraph 3.3.2 */ +#define ITD_TSCL_XOFFS_SHIFT (0) /* Bits 0-11: Transaction X offset */ +#define ITD_TSCL_XOFFS_MASK (0xfff << ITD_TSCL_XOFFS_SHIFT) +#define ITD_TSCL_PG_SHIFT (12) /* Bits 12-14: Page select */ +#define ITD_TSCL_PG_MASK (7 << ITD_TSCL_PG_SHIFT) +#define ITD_TSCL_IOC (1 << 15) /* Bit 15: Interrupt On Comp */ +#define ITD_TSCL_LENGTH_SHIFT (16) /* Bits 16-27: Transaction length */ +#define ITD_TSCL_LENGTH_MASK (0xfff << ITD_TSCL_LENGTH_SHIFT) +#define ITD_TSCL_STATUS_SHIFT (28) /* Bits 28-31: Transaction status */ +#define ITD_TSCL_STATUS_MASK (15 << ITD_TSCL_STATUS_SHIFT) +#define ITD_TSCL_STATUS_XACTERR (1 << 28) /* Bit 28: Transaction error */ +#define ITD_TSCL_STATUS_BABBLE (1 << 29) /* Bit 29: Babble Detected */ +#define ITD_TSCL_STATUS_DBERROR (1 << 30) /* Bit 30: Data Buffer Error */ +#define ITD_TSCL_STATUS_ACTIVE (1 << 31) /* Bit 31: Active error */ + +/* iTD Buffer Page Pointer List. Paragraph 3.3.4 */ + +/* iTD Buffer Pointer Page 0. Table 3-4 */ + +#define ITD_BUFPTR0_DEVADDR_SHIFT (0) /* Bits 0-6: Device Address */ +#define ITD_BUFPTR0_DEVADDR_MASK (0x7f << ITD_BUFPTR0_DEVADDR_SHIFT) +#define ITD_BUFPTR0_ENDPT_SHIFT (8) /* Bits 8-11: Endpoint Number */ +#define ITD_BUFPTR0_ENDPT_MASK (15 << ITD_BUFPTR0_ENDPT_SHIFT) + +/* iTD Buffer Pointer Page 1. Table 3-5 */ + +#define ITD_BUFPTR1_MAXPKT_SHIFT (0) /* Bits 0-10: Maximum Packet Size */ +#define ITD_BUFPTR1_MAXPKT_MASK (0x7ff << ITD_BUFPTR1_MAXPKT_SHIFT) +#define ITD_BUFPTR1_DIRIN (1 << 11) /* Bit 11: Direction 1=IN */ +#define ITD_BUFPTR1_DIROUT (0) /* Bit 11: Direction 0=OUT */ + +/* iTD Buffer Pointer Page 2. Table 3-6 */ + +#define ITD_BUFPTR2_MULTI_SHIFT (0) /* Bits 0-1: Multi */ +#define ITD_BUFPTR2_MULTI_MASK (3 << ITD_BUFPTR2_MULTI_SHIFT) +#define ITD_BUFPTR2_MULTI_1 (1 << ITD_BUFPTR2_MULTI_SHIFT) /* One transaction per micro-frame */ +#define ITD_BUFPTR2_MULTI_2 (2 << ITD_BUFPTR2_MULTI_SHIFT) /* Two transactions per micro-frame */ +#define ITD_BUFPTR2_MULTI_3 (3 << ITD_BUFPTR2_MULTI_SHIFT) /* Three transactions per micro-frame */ + +/* Registers ****************************************************************/ + +/* Host Controller Capability Registers. + * This register block must be positioned at a well known address. + */ + +struct ehci_hccr { + volatile uint8_t caplength; /* 0x00: Capability Register Length */ + volatile uint8_t reserved; /* 0x01: reserved */ + volatile uint16_t hciversion; /* 0x02: Interface Version Number */ + volatile uint32_t hcsparams; /* 0x04: Structural Parameters */ + volatile uint32_t hccparams; /* 0x08: Capability Parameters */ + volatile uint8_t hcspportroute[8]; /* 0x0c: Companion Port Route Description */ +}; + +/* Host Controller Operational Registers. + * This register block is positioned at an offset of 'caplength' from the + * beginning of the Host Controller Capability Registers. + */ + +struct ehci_hcor { + volatile uint32_t usbcmd; /* 0x00: USB Command */ + volatile uint32_t usbsts; /* 0x04: USB Status */ + volatile uint32_t usbintr; /* 0x08: USB Interrupt Enable */ + volatile uint32_t frindex; /* 0x0c: USB Frame Index */ + volatile uint32_t ctrldssegment; /* 0x10: 4G Segment Selector */ + volatile uint32_t periodiclistbase; /* 0x14: Frame List Base Address */ + volatile uint32_t asynclistaddr; /* 0x18: Next Asynchronous List Address */ +#ifndef CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE + uint32_t reserved[9]; +#endif + volatile uint32_t configflag; /* 0x40: Configured Flag Register */ + volatile uint32_t portsc[15]; /* 0x44: Port Status/Control */ +}; + +/* USB2 Debug Port Register Interface. + * This register block is normally found via the PCI capabalities. + * In non-PCI implementions, you need apriori information about the + * location of these registers. + */ + +struct ehci_debug { + uint32_t psc; /* 0x00: Debug Port Control/Status Register */ + uint32_t pids; /* 0x04: Debug USB PIDs Register */ + uint32_t data[2]; /* 0x08: Debug Data buffer Registers */ + uint32_t addr; /* 0x10: Device Address Register */ +}; + +/* Data Structures **********************************************************/ + +/* Queue Element Transfer Descriptor (qTD). Paragraph 3.5 */ + +struct ehci_qtd { + uint32_t next_qtd; /* 0x00-0x03: Next qTD Pointer */ + uint32_t alt_next_qtd; /* 0x04-0x07: Alternate Next qTD Pointer */ + uint32_t token; /* 0x08-0x0b: qTD Token */ + uint32_t bpl[5]; /* 0x0c-0x1c: Buffer Page Pointer List */ +}; + +#define SIZEOF_EHCI_QTD (32) /* 8*sizeof(uint32_t) */ + +/* Queue Head. Paragraph 3.6 */ + +struct ehci_qh { + uint32_t hlp; /* 0x00-0x03: Queue Head Horizontal Link Pointer */ + uint32_t epchar; /* 0x04-0x07: Endpoint Characteristics */ + uint32_t epcap; /* 0x08-0x0b: Endpoint Capabilities */ + uint32_t curr_qtd; /* 0x0c-0x0f: Current qTD Pointer */ + struct ehci_qtd overlay; /* 0x10-0x2c: Transfer overlay */ +}; + +#define SIZEOF_EHCI_QH (48) /* 4*sizeof(uint32_t) + 32 */ + +/* Isochronous (High-Speed) Transfer Descriptor (iTD). + * Paragraph 3.3. Must be aligned to 32-byte boundaries. + */ + +struct ehci_itd { + uint32_t nlp; /* 0x00-0x03: Next link pointer */ + uint32_t tscl[8]; /* 0x04-0x23: Transaction Status and Control List */ + uint32_t bpl[7]; /* 0x24-0x3c: Buffer Page Pointer List */ +}; + +#define SIZEOF_EHCI_ITD (64) /* 16*sizeof(uint32_t) */ + +/* Split Transaction Isochronous Transfer Descriptor (siTD). Paragraph 3.4 */ + +struct ehci_sitd { + uint32_t nlp; /* 0x00-0x03: Next link pointer */ + uint32_t epchar; /* 0x04-0x07: Endpoint and Transaction Translator Characteristics */ + uint32_t mfsc; /* 0x08-0x0b: Micro-frame Schedule Control */ + uint32_t tsc; /* 0x0c-0x0f: Transfer Status and Control */ + uint32_t bpl[2]; /* 0x10-0x17: Buffer Pointer List */ + uint32_t blp; /* 0x18-0x1b: Back link pointer */ +}; + +#define SIZEOF_EHCI_SITD (28) /* 7*sizeof(uint32_t) */ + +#endif /* __INCLUDE_NUTTX_USB_EHCI_H */ diff --git a/port/ehci/usb_glue_aic.c b/port/ehci/usb_glue_aic.c index 5445b535..9fc87c39 100644 --- a/port/ehci/usb_glue_aic.c +++ b/port/ehci/usb_glue_aic.c @@ -8,7 +8,7 @@ #include #include #include "usbh_core.h" -#include "usb_ehci_priv.h" +#include "usb_hc_ehci.h" extern void USBH_IRQHandler(uint8_t busid); diff --git a/port/ehci/usb_hc_ehci.c b/port/ehci/usb_hc_ehci.c index d8370120..cdb2362e 100644 --- a/port/ehci/usb_hc_ehci.c +++ b/port/ehci/usb_hc_ehci.c @@ -3,9 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include "usb_ehci_priv.h" +#include "usb_hc_ehci.h" #ifdef CONFIG_USB_EHCI_WITH_OHCI -#include "usb_ohci_priv.h" +#include "usb_hc_ohci.h" #endif #define EHCI_TUNE_CERR 3 /* 0-3 qtd retries; 0 == don't stop */ diff --git a/port/ehci/usb_hc_ehci.h b/port/ehci/usb_hc_ehci.h index 7f3febc2..714128bc 100644 --- a/port/ehci/usb_hc_ehci.h +++ b/port/ehci/usb_hc_ehci.h @@ -1,375 +1,84 @@ /* - * Copyright 2020 The Apache Software Foundation - * Copyright 2022 sakumisu - * + * Copyright (c) 2022, sakumisu + * * SPDX-License-Identifier: Apache-2.0 */ -#ifndef USB_HC_EHCI_H -#define USB_HC_EHCI_H +#ifndef _USB_EHCI_PRIV_H +#define _USB_EHCI_PRIV_H -#define EHCI_FULL_SPEED (0) /* Full-Speed (12Mbs) */ -#define EHCI_LOW_SPEED (1) /* Low-Speed (1.5Mbs) */ -#define EHCI_HIGH_SPEED (2) /* High-Speed (480 Mb/s) */ +#include "usbh_core.h" +#include "usbh_hub.h" +#include "usb_ehci_reg.h" -/* Host Controller Capability Register Bit Definitions **********************/ +#define EHCI_HCCR ((struct ehci_hccr *)(uintptr_t)(bus->hcd.reg_base + CONFIG_USB_EHCI_HCCR_OFFSET)) +#define EHCI_HCOR ((struct ehci_hcor *)(uintptr_t)(bus->hcd.reg_base + CONFIG_USB_EHCI_HCCR_OFFSET + g_ehci_hcd[bus->hcd.hcd_id].hcor_offset)) -/* Structural Parameters. Paragraph 2.2.3 */ +#define EHCI_PTR2ADDR(x) ((uint32_t)(uintptr_t)(x) & ~0x1F) +#define EHCI_ADDR2QH(x) ((struct ehci_qh_hw *)(uintptr_t)((uint32_t)(x) & ~0x1F)) +#define EHCI_ADDR2QTD(x) ((struct ehci_qtd_hw *)(uintptr_t)((uint32_t)(x) & ~0x1F)) +#define EHCI_ADDR2ITD(x) ((struct ehci_itd_hw *)(uintptr_t)((uint32_t)(x) & ~0x1F)) -#define EHCI_HCSPARAMS_NPORTS_SHIFT (0) /* Bit 0-3: Number of physical downstream ports */ -#define EHCI_HCSPARAMS_NPORTS_MASK (15 << EHCI_HCSPARAMS_NPORTS_SHIFT) -#define EHCI_HCSPARAMS_PPC (1 << 4) /* Bit 4: Port Power Control */ -#define EHCI_HCSPARAMS_PRR (1 << 7) /* Bit 7: Port Routing Rules */ -#define EHCI_HCSPARAMS_NPCC_SHIFT (8) /* Bit 8-11: Number of Ports per Companion Controller */ -#define EHCI_HCSPARAMS_NPCC_MASK (15 << EHCI_HCSPARAMS_NPCC_SHIFT) -#define EHCI_HCSPARAMS_NCC_SHIFT (12) /* Bit 12-15: Number of Companion Controllers */ -#define EHCI_HCSPARAMS_NCC_MASK (15 << EHCI_HCSPARAMS_NCC_SHIFT) -#define EHCI_HCSPARAMS_PIND (1 << 16) /* Bit 16: Port Indicators */ -#define EHCI_HCSPARAMS_DBGPORT_SHIFT (20) /* Bit 20-23: Debug Port Number */ -#define EHCI_HCSPARAMS_DBGPORT_MASK (15 << EHCI_HCSPARAMS_DBGPORT_SHIFT) - -/* Capability Parameters. Paragraph 2.2.4 */ - -#define EHCI_HCCPARAMS_64BIT (1 << 0) /* Bit 0: 64-bit Addressing Capability */ -#define EHCI_HCCPARAMS_PFLF (1 << 1) /* Bit 1: Programmable Frame List Flag */ -#define EHCI_HCCPARAMS_ASPC (1 << 2) /* Bit 2: Asynchronous Schedule Park Capability */ -#define EHCI_HCCPARAMS_IST_SHIFT (4) /* Bits 4-7: Isochronous Scheduling Threshold */ -#define EHCI_HCCPARAMS_IST_MASK (15 << EHCI_HCCPARAMS_IST_SHIFT) -#define EHCI_HCCPARAMS_EECP_SHIFT (8) /* Bits 8-15: EHCI Extended Capabilities Pointer */ -#define EHCI_HCCPARAMS_EECP_MASK (0xff << EHCI_HCCPARAMS_EECP_SHIFT) - -/* Host Controller Operational Register Bit Definitions *********************/ - -/* USB Command. Paragraph 2.3.1 */ - -#define EHCI_USBCMD_RUN (1 << 0) /* Bit 0: Run/Stop */ -#define EHCI_USBCMD_HCRESET (1 << 1) /* Bit 1: Host Controller Reset */ -#define EHCI_USBCMD_FLSIZE_SHIFT (2) /* Bits 2-3: Frame List Size */ -#define EHCI_USBCMD_FLSIZE_MASK (3 << EHCI_USBCMD_FLSIZE_SHIFT) -#define EHCI_USBCMD_FLSIZE_1024 (0 << EHCI_USBCMD_FLSIZE_SHIFT) /* 1024 elements (4096 bytes) */ -#define EHCI_USBCMD_FLSIZE_512 (1 << EHCI_USBCMD_FLSIZE_SHIFT) /* 512 elements (2048 bytes) */ -#define EHCI_USBCMD_FLSIZE_256 (2 << EHCI_USBCMD_FLSIZE_SHIFT) /* 256 elements (1024 bytes) */ -#define EHCI_USBCMD_PSEN (1 << 4) /* Bit 4: Periodic Schedule Enable */ -#define EHCI_USBCMD_ASEN (1 << 5) /* Bit 5: Asynchronous Schedule Enable */ -#define EHCI_USBCMD_IAAD (1 << 6) /* Bit 6: Interrupt on Async Advance Doorbell */ -#define EHCI_USBCMD_LRESET (1 << 7) /* Bit 7: Light Host Controller Reset */ -#define EHCI_USBCMD_ASYNC_PARKCNT_SHIFT (8) /* Bits 8-9: Asynchronous Schedule Park Mode Count */ -#define EHCI_USBCMD_ASYNC_PARKCNT_MASK (3 << EHCI_USBCMD_ASYNC_PARKCNT_SHIFT) -#define EHCI_USBCMD_ASYNC_PARK (1 << 11) /* Bit 11: Asynchronous Schedule Park Mode Enable */ -#define EHCI_USBCMD_ITHRE_SHIFT (16) /* Bits 16-23: Interrupt Threshold Control */ -#define EHCI_USBCMD_ITHRE_MASK (0xff << EHCI_USBCMD_ITHRE_SHIFT) -#define EHCI_USBCMD_ITHRE_1MF (0x01 << EHCI_USBCMD_ITHRE_SHIFT) /* 1 micro-frame */ -#define EHCI_USBCMD_ITHRE_2MF (0x02 << EHCI_USBCMD_ITHRE_SHIFT) /* 2 micro-frames */ -#define EHCI_USBCMD_ITHRE_4MF (0x04 << EHCI_USBCMD_ITHRE_SHIFT) /* 4 micro-frames */ -#define EHCI_USBCMD_ITHRE_8MF (0x08 << EHCI_USBCMD_ITHRE_SHIFT) /* 8 micro-frames (default, 1 ms) */ -#define EHCI_USBCMD_ITHRE_16MF (0x10 << EHCI_USBCMD_ITHRE_SHIFT) /* 16 micro-frames (2 ms) */ -#define EHCI_USBCMD_ITHRE_32MF (0x20 << EHCI_USBCMD_ITHRE_SHIFT) /* 32 micro-frames (4 ms) */ -#define EHCI_USBCMD_ITHRE_64MF (0x40 << EHCI_USBCMD_ITHRE_SHIFT) /* 64 micro-frames (8 ms) */ - -/* USB Status. Paragraph 2.3.2 */ - -#define EHCI_USBSTS_INT (1 << 0) /* Bit 0: USB Interrupt */ -#define EHCI_USBSTS_ERR (1 << 1) /* Bit 1: USB Error Interrupt */ -#define EHCI_USBSTS_PCD (1 << 2) /* Bit 2: Port Change Detect */ -#define EHCI_USBSTS_FLR (1 << 3) /* Bit 3: Frame List Rollover */ -#define EHCI_USBSTS_FATAL (1 << 4) /* Bit 4: Host System Error */ -#define EHCI_USBSTS_IAA (1 << 5) /* Bit 5: Interrupt on Async Advance */ -#define EHCI_USBSTS_HALTED (1 << 12) /* Bit 12: HC Halted */ -#define EHCI_USBSTS_RECLAM (1 << 13) /* Bit 13: Reclamation */ -#define EHCI_USBSTS_PSS (1 << 14) /* Bit 14: Periodic Schedule Status */ -#define EHCI_USBSTS_ASS (1 << 15) /* Bit 15: Asynchronous Schedule Status */ - /* Bits 16-31: Reserved */ - -/* USB Interrupt Enable. Paragraph 2.3.3 */ - -#define EHCI_USBIE_INT (1 << 0) /* Bit 0: USB Interrupt */ -#define EHCI_USBIE_ERR (1 << 1) /* Bit 1: USB Error Interrupt */ -#define EHCI_USBIE_PCD (1 << 2) /* Bit 2: Port Change Detect */ -#define EHCI_USBIE_FLROLL (1 << 3) /* Bit 3: Frame List Rollover */ -#define EHCI_USBIE_FATAL (1 << 4) /* Bit 4: Host System Error */ -#define EHCI_USBIE_IAA (1 << 5) /* Bit 5: Interrupt on Async Advance */ -#define EHCI_USBIE_ALLINTS (0x3f) /* Bits 0-5: All interrupts */ - -/* USB Frame Index. Paragraph 2.3.4 */ - -#define EHCI_FRINDEX_MASK (0x3fff) /* Bits 0-13: Frame index */ - -/* 4G Segment Selector. - * Paragraph 2.3.5, Bits[64:32] of data structure addresses - */ - -/* Frame List Base Address. Paragraph 2.3.6 */ -#define EHCI_PERIODICLISTBASE_MASK (0xfffff000) /* Bits 12-31: Base Address (Low) */ - -/* Next Asynchronous List Address. Paragraph 2.3.7 */ - -#define EHCI_ASYNCLISTADDR_MASK (0xffffffe0) /* Bits 5-31: Link Pointer Low (LPL) */ - -/* Configured Flag Register. Paragraph 2.3.8 */ - -#define EHCI_CONFIGFLAG (1 << 0) /* Bit 0: Configure Flag */ - -/* Port Status/Control, Port 1-n. Paragraph 2.3.9 */ - -#define EHCI_PORTSC_CCS (1 << 0) /* Bit 0: Current Connect Status */ -#define EHCI_PORTSC_CSC (1 << 1) /* Bit 1: Connect Status Change */ -#define EHCI_PORTSC_PE (1 << 2) /* Bit 2: Port Enable */ -#define EHCI_PORTSC_PEC (1 << 3) /* Bit 3: Port Enable/Disable Change */ -#define EHCI_PORTSC_OCA (1 << 4) /* Bit 4: Over-current Active */ -#define EHCI_PORTSC_OCC (1 << 5) /* Bit 5: Over-current Change */ -#define EHCI_PORTSC_RESUME (1 << 6) /* Bit 6: Force Port Resume */ -#define EHCI_PORTSC_SUSPEND (1 << 7) /* Bit 7: Suspend */ -#define EHCI_PORTSC_RESET (1 << 8) /* Bit 8: Port Reset */ -#define EHCI_PORTSC_LSTATUS_SHIFT (10) /* Bits 10-11: Line Status */ -#define EHCI_PORTSC_LSTATUS_MASK (3 << EHCI_PORTSC_LSTATUS_SHIFT) -#define EHCI_PORTSC_LSTATUS_SE0 (0 << EHCI_PORTSC_LSTATUS_SHIFT) /* SE0 Not Low-speed device, perform EHCI reset */ -#define EHCI_PORTSC_LSTATUS_KSTATE (1 << EHCI_PORTSC_LSTATUS_SHIFT) /* K-state Low-speed device, release ownership of port */ -#define EHCI_PORTSC_LSTATUS_JSTATE (2 << EHCI_PORTSC_LSTATUS_SHIFT) /* J-state Not Low-speed device, perform EHCI reset */ -#define EHCI_PORTSC_PP (1 << 12) /* Bit 12: Port Power */ -#define EHCI_PORTSC_OWNER (1 << 13) /* Bit 13: Port Owner */ -#define EHCI_PORTSC_PIC_SHIFT (14) /* Bits 14-15: Port Indicator Control */ -#define EHCI_PORTSC_PIC_MASK (3 << EHCI_PORTSC_PIC_SHIFT) -#define EHCI_PORTSC_PIC_OFF (0 << EHCI_PORTSC_PIC_SHIFT) /* Port indicators are off */ -#define EHCI_PORTSC_PIC_AMBER (1 << EHCI_PORTSC_PIC_SHIFT) /* Amber */ -#define EHCI_PORTSC_PIC_GREEN (2 << EHCI_PORTSC_PIC_SHIFT) /* Green */ -#define EHCI_PORTSC_PTC_SHIFT (16) /* Bits 16-19: Port Test Control */ -#define EHCI_PORTSC_PTC_MASK (15 << EHCI_PORTSC_PTC_SHIFT) -#define EHCI_PORTSC_PTC_DISABLED (0 << EHCI_PORTSC_PTC_SHIFT) /* Test mode not enabled */ -#define EHCI_PORTSC_PTC_JSTATE (1 << EHCI_PORTSC_PTC_SHIFT) /* Test J_STATE */ -#define EHCI_PORTSC_PTC_KSTATE (2 << EHCI_PORTSC_PTC_SHIFT) /* Test K_STATE */ -#define EHCI_PORTSC_PTC_SE0NAK (3 << EHCI_PORTSC_PTC_SHIFT) /* Test SE0_NAK */ -#define EHCI_PORTSC_PTC_PACKET (4 << EHCI_PORTSC_PTC_SHIFT) /* Test Packet */ -#define EHCI_PORTSC_PTC_ENABLE (5 << EHCI_PORTSC_PTC_SHIFT) /* Test FORCE_ENABLE */ -#define EHCI_PORTSC_WKCCNTE (1 << 20) /* Bit 20: Wake on Connect Enable */ -#define EHCI_PORTSC_WKDSCNNTE (1 << 21) /* Bit 21: Wake on Disconnect Enable */ -#define EHCI_PORTSC_WKOCE (1 << 22) /* Bit 22: Wake on Over-current Enable */ - /* Bits 23-31: Reserved */ - -#define EHCI_PORTSC_ALLINTS (EHCI_PORTSC_CSC | EHCI_PORTSC_PEC | \ - EHCI_PORTSC_OCC | EHCI_PORTSC_RESUME) - -/* Queue Head. Paragraph 3.6 */ - -/* Queue Head Horizontal Link Pointer: Queue Head DWord 0. Table 3-19 */ - -#define QH_HLP_END 0x1 - -#define QH_HLP_ITD(x) (((uint32_t)(x) & ~0x1F) | 0x0) /* Isochronous Transfer Descriptor */ -#define QH_HLP_QH(x) (((uint32_t)(x) & ~0x1F) | 0x2) /* Queue Head */ -#define QH_HLP_SITD(x) (((uint32_t)(x) & ~0x1F) | 0x4) /* Split Transaction Isochronous Transfer Descriptor */ -#define QH_HLP_FSTN(x) (((uint32_t)(x) & ~0x1F) | 0x6) /* Frame Span Traversal Node */ - -/* Endpoint Characteristics: Queue Head DWord 1. Table 3-19 */ - -#define QH_EPCHAR_DEVADDR_SHIFT (0) /* Bitx 0-6: Device Address */ -#define QH_EPCHAR_DEVADDR_MASK (0x7f << QH_EPCHAR_DEVADDR_SHIFT) -#define QH_EPCHAR_I (1 << 7) /* Bit 7: Inactivate on Next Transaction */ -#define QH_EPCHAR_ENDPT_SHIFT (8) /* Bitx 8-11: Endpoint Number */ -#define QH_EPCHAR_ENDPT_MASK (15 << QH_EPCHAR_ENDPT_SHIFT) -#define QH_EPCHAR_EPS_SHIFT (12) /* Bitx 12-13: Endpoint Speed */ -#define QH_EPCHAR_EPS_MASK (3 << QH_EPCHAR_EPS_SHIFT) -#define QH_EPCHAR_EPS_FULL (0 << QH_EPCHAR_EPS_SHIFT) /* Full-Speed (12Mbs) */ -#define QH_EPCHAR_EPS_LOW (1 << QH_EPCHAR_EPS_SHIFT) /* Low-Speed (1.5Mbs) */ -#define QH_EPCHAR_EPS_HIGH (2 << QH_EPCHAR_EPS_SHIFT) /* High-Speed (480 Mb/s) */ -#define QH_EPCHAR_DTC (1 << 14) /* Bit 14: Data Toggle Control */ -#define QH_EPCHAR_H (1 << 15) /* Bit 15: Head of Reclamation List Flag */ -#define QH_EPCHAR_MAXPKT_SHIFT (16) /* Bitx 16-26: Maximum Packet Length */ -#define QH_EPCHAR_MAXPKT_MASK (0x7ff << QH_EPCHAR_MAXPKT_SHIFT) -#define QH_EPCHAR_C (1 << 27) /* Bit 27: Control Endpoint Flag */ -#define QH_EPCHAR_RL_SHIFT (28) /* Bitx 28-31: Nak Count Reload */ -#define QH_EPCHAR_RL_MASK (15 << QH_EPCHAR_RL_SHIFT) - -/* Endpoint Capabilities: Queue Head DWord 2. Table 3-20 */ - -#define QH_EPCAPS_SSMASK_SHIFT (0) /* Bitx 0-7: Interrupt Schedule Mask (Frame S-mask) */ -#define QH_EPCAPS_SSMASK_MASK (0xff << QH_EPCAPS_SSMASK_SHIFT) -#define QH_EPCAPS_SSMASK(n) ((n) << QH_EPCAPS_SSMASK_SHIFT) -#define QH_EPCAPS_SCMASK_SHIFT (8) /* Bitx 8-15: Split Completion Mask (Frame C-Mask) */ -#define QH_EPCAPS_SCMASK_MASK (0xff << QH_EPCAPS_SCMASK_SHIFT) -#define QH_EPCAPS_SCMASK(n) ((n) << QH_EPCAPS_SCMASK_SHIFT) -#define QH_EPCAPS_HUBADDR_SHIFT (16) /* Bitx 16-22: Hub Address */ -#define QH_EPCAPS_HUBADDR_MASK (0x7f << QH_EPCAPS_HUBADDR_SHIFT) -#define QH_EPCAPS_HUBADDR(n) ((n) << QH_EPCAPS_HUBADDR_SHIFT) -#define QH_EPCAPS_PORT_SHIFT (23) /* Bit 23-29: Port Number */ -#define QH_EPCAPS_PORT_MASK (0x7f << QH_EPCAPS_PORT_SHIFT) -#define QH_EPCAPS_PORT(n) ((n) << QH_EPCAPS_PORT_SHIFT) -#define QH_EPCAPS_MULT_SHIFT (30) /* Bit 30-31: High-Bandwidth Pipe Multiplier */ -#define QH_EPCAPS_MULT_MASK (3 << QH_EPCAPS_MULT_SHIFT) -#define QH_EPCAPS_MULT(n) ((n) << QH_EPCAPS_MULT_SHIFT) - -/* qTD Token. Paragraph 3.5.3 */ - -#define QTD_LIST_END 1 - -#define QTD_TOKEN_STATUS_SHIFT (0) /* Bits 0-7: Status */ -#define QTD_TOKEN_STATUS_MASK (0xff << QTD_TOKEN_STATUS_SHIFT) -#define QTD_TOKEN_STATUS_PINGSTATE (1 << 0) /* Bit 0 Ping State */ -#define QTD_TOKEN_STATUS_ERR (1 << 0) /* Bit 0 Error */ -#define QTD_TOKEN_STATUS_SPLITXSTATE (1 << 1) /* Bit 1 Split Transaction State */ -#define QTD_TOKEN_STATUS_MMF (1 << 2) /* Bit 2 Missed Micro-Frame */ -#define QTD_TOKEN_STATUS_XACTERR (1 << 3) /* Bit 3 Transaction Error */ -#define QTD_TOKEN_STATUS_BABBLE (1 << 4) /* Bit 4 Babble Detected */ -#define QTD_TOKEN_STATUS_DBERR (1 << 5) /* Bit 5 Data Buffer Error */ -#define QTD_TOKEN_STATUS_HALTED (1 << 6) /* Bit 6 Halted */ -#define QTD_TOKEN_STATUS_ACTIVE (1 << 7) /* Bit 7 Active */ -#define QTD_TOKEN_STATUS_ERRORS (0x78 << QTD_TOKEN_STATUS_SHIFT) -#define QTD_TOKEN_PID_SHIFT (8) /* Bits 8-9: PID Code */ -#define QTD_TOKEN_PID_MASK (3 << QTD_TOKEN_PID_SHIFT) -#define QTD_TOKEN_PID_OUT (0 << QTD_TOKEN_PID_SHIFT) /* OUT Token generates token (E1H) */ -#define QTD_TOKEN_PID_IN (1 << QTD_TOKEN_PID_SHIFT) /* IN Token generates token (69H) */ -#define QTD_TOKEN_PID_SETUP (2 << QTD_TOKEN_PID_SHIFT) /* SETUP Token generates token (2DH) */ -#define QTD_TOKEN_CERR_SHIFT (10) /* Bits 10-11: Error Counter */ -#define QTD_TOKEN_CERR_MASK (3 << QTD_TOKEN_CERR_SHIFT) -#define QTD_TOKEN_CPAGE_SHIFT (12) /* Bits 12-14: Current Page */ -#define QTD_TOKEN_CPAGE_MASK (7 << QTD_TOKEN_CPAGE_SHIFT) -#define QTD_TOKEN_IOC (1 << 15) /* Bit 15: Interrupt On Complete */ -#define QTD_TOKEN_NBYTES_SHIFT (16) /* Bits 16-30: Total Bytes to Transfer */ -#define QTD_TOKEN_NBYTES_MASK (0x7fff << QTD_TOKEN_NBYTES_SHIFT) -#define QTD_TOKEN_TOGGLE (1 << 31) /* Bit 31: Data Toggle */ - -/* Isochronous (High-Speed) Transfer Descriptor (iTD). Paragraph 3.3 */ - -/* iTD Next Link Pointer. Paragraph 3.3.1 */ - -#define ITD_NLP_ITD(x) (((uint32_t)(x) & ~0x1F) | 0x0) -#define ITD_NLP_QH(x) (((uint32_t)(x) & ~0x1F) | 0x2) -#define ITD_NLP_SITD(x) (((uint32_t)(x) & ~0x1F) | 0x4) -#define ITD_NLP_FSTN(x) (((uint32_t)(x) & ~0x1F) | 0x6) - -/* iTD Transaction Status and Control List. Paragraph 3.3.2 */ -#define ITD_TSCL_XOFFS_SHIFT (0) /* Bits 0-11: Transaction X offset */ -#define ITD_TSCL_XOFFS_MASK (0xfff << ITD_TSCL_XOFFS_SHIFT) -#define ITD_TSCL_PG_SHIFT (12) /* Bits 12-14: Page select */ -#define ITD_TSCL_PG_MASK (7 << ITD_TSCL_PG_SHIFT) -#define ITD_TSCL_IOC (1 << 15) /* Bit 15: Interrupt On Comp */ -#define ITD_TSCL_LENGTH_SHIFT (16) /* Bits 16-27: Transaction length */ -#define ITD_TSCL_LENGTH_MASK (0xfff << ITD_TSCL_LENGTH_SHIFT) -#define ITD_TSCL_STATUS_SHIFT (28) /* Bits 28-31: Transaction status */ -#define ITD_TSCL_STATUS_MASK (15 << ITD_TSCL_STATUS_SHIFT) -#define ITD_TSCL_STATUS_XACTERR (1 << 28) /* Bit 28: Transaction error */ -#define ITD_TSCL_STATUS_BABBLE (1 << 29) /* Bit 29: Babble Detected */ -#define ITD_TSCL_STATUS_DBERROR (1 << 30) /* Bit 30: Data Buffer Error */ -#define ITD_TSCL_STATUS_ACTIVE (1 << 31) /* Bit 31: Active error */ - -/* iTD Buffer Page Pointer List. Paragraph 3.3.4 */ - -/* iTD Buffer Pointer Page 0. Table 3-4 */ - -#define ITD_BUFPTR0_DEVADDR_SHIFT (0) /* Bits 0-6: Device Address */ -#define ITD_BUFPTR0_DEVADDR_MASK (0x7f << ITD_BUFPTR0_DEVADDR_SHIFT) -#define ITD_BUFPTR0_ENDPT_SHIFT (8) /* Bits 8-11: Endpoint Number */ -#define ITD_BUFPTR0_ENDPT_MASK (15 << ITD_BUFPTR0_ENDPT_SHIFT) - -/* iTD Buffer Pointer Page 1. Table 3-5 */ - -#define ITD_BUFPTR1_MAXPKT_SHIFT (0) /* Bits 0-10: Maximum Packet Size */ -#define ITD_BUFPTR1_MAXPKT_MASK (0x7ff << ITD_BUFPTR1_MAXPKT_SHIFT) -#define ITD_BUFPTR1_DIRIN (1 << 11) /* Bit 11: Direction 1=IN */ -#define ITD_BUFPTR1_DIROUT (0) /* Bit 11: Direction 0=OUT */ - -/* iTD Buffer Pointer Page 2. Table 3-6 */ - -#define ITD_BUFPTR2_MULTI_SHIFT (0) /* Bits 0-1: Multi */ -#define ITD_BUFPTR2_MULTI_MASK (3 << ITD_BUFPTR2_MULTI_SHIFT) -#define ITD_BUFPTR2_MULTI_1 (1 << ITD_BUFPTR2_MULTI_SHIFT) /* One transaction per micro-frame */ -#define ITD_BUFPTR2_MULTI_2 (2 << ITD_BUFPTR2_MULTI_SHIFT) /* Two transactions per micro-frame */ -#define ITD_BUFPTR2_MULTI_3 (3 << ITD_BUFPTR2_MULTI_SHIFT) /* Three transactions per micro-frame */ - -/* Registers ****************************************************************/ - -/* Host Controller Capability Registers. - * This register block must be positioned at a well known address. - */ - -struct ehci_hccr { - volatile uint8_t caplength; /* 0x00: Capability Register Length */ - volatile uint8_t reserved; /* 0x01: reserved */ - volatile uint16_t hciversion; /* 0x02: Interface Version Number */ - volatile uint32_t hcsparams; /* 0x04: Structural Parameters */ - volatile uint32_t hccparams; /* 0x08: Capability Parameters */ - volatile uint8_t hcspportroute[8]; /* 0x0c: Companion Port Route Description */ -}; - -/* Host Controller Operational Registers. - * This register block is positioned at an offset of 'caplength' from the - * beginning of the Host Controller Capability Registers. - */ - -struct ehci_hcor { - volatile uint32_t usbcmd; /* 0x00: USB Command */ - volatile uint32_t usbsts; /* 0x04: USB Status */ - volatile uint32_t usbintr; /* 0x08: USB Interrupt Enable */ - volatile uint32_t frindex; /* 0x0c: USB Frame Index */ - volatile uint32_t ctrldssegment; /* 0x10: 4G Segment Selector */ - volatile uint32_t periodiclistbase; /* 0x14: Frame List Base Address */ - volatile uint32_t asynclistaddr; /* 0x18: Next Asynchronous List Address */ -#ifndef CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE - uint32_t reserved[9]; +#ifndef CONFIG_USB_EHCI_QH_NUM +#define CONFIG_USB_EHCI_QH_NUM CONFIG_USBHOST_PIPE_NUM #endif - volatile uint32_t configflag; /* 0x40: Configured Flag Register */ - volatile uint32_t portsc[15]; /* 0x44: Port Status/Control */ +#ifndef CONFIG_USB_EHCI_QTD_NUM +#define CONFIG_USB_EHCI_QTD_NUM 3 +#endif +#ifndef CONFIG_USB_EHCI_ITD_NUM +#define CONFIG_USB_EHCI_ITD_NUM 5 +#endif +#ifndef CONFIG_USB_EHCI_ISO_NUM +#define CONFIG_USB_EHCI_ISO_NUM 4 +#endif + +extern uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port); + +struct ehci_qtd_hw { + struct ehci_qtd hw; + struct usbh_urb *urb; + uint32_t length; +} __attribute__((aligned(32))); + +struct ehci_qh_hw { + struct ehci_qh hw; + struct ehci_qtd_hw qtd_pool[CONFIG_USB_EHCI_QTD_NUM]; + uint32_t first_qtd; + struct usbh_urb *urb; + usb_osal_sem_t waitsem; + uint8_t remove_in_iaad; +} __attribute__((aligned(32))); + +struct ehci_itd_hw { + struct ehci_itd hw; + struct usbh_urb *urb; + uint16_t start_frame; + uint8_t mf_unmask; + uint8_t mf_valid; + uint32_t pkt_idx[8]; +} __attribute__((aligned(32))); + +struct ehci_iso_hw +{ + struct ehci_itd_hw itd_pool[CONFIG_USB_EHCI_ITD_NUM]; + uint32_t itd_num; }; -/* USB2 Debug Port Register Interface. - * This register block is normally found via the PCI capabalities. - * In non-PCI implementions, you need apriori information about the - * location of these registers. - */ - -struct ehci_debug { - uint32_t psc; /* 0x00: Debug Port Control/Status Register */ - uint32_t pids; /* 0x04: Debug USB PIDs Register */ - uint32_t data[2]; /* 0x08: Debug Data buffer Registers */ - uint32_t addr; /* 0x10: Device Address Register */ +struct ehci_hcd { + bool ehci_qh_used[CONFIG_USB_EHCI_QH_NUM]; + bool ehci_iso_used[CONFIG_USB_EHCI_ISO_NUM]; + bool ppc; /* Port Power Control */ + bool has_tt; /* if use tt instead of Companion Controller */ + uint8_t n_cc; /* Number of Companion Controller */ + uint8_t n_pcc; /* Number of ports supported per companion host controller */ + uint8_t n_ports; + uint8_t hcor_offset; }; -/* Data Structures **********************************************************/ +extern struct ehci_hcd g_ehci_hcd[CONFIG_USBHOST_MAX_BUS]; +extern uint32_t g_framelist[CONFIG_USBHOST_MAX_BUS][USB_ALIGN_UP(CONFIG_USB_EHCI_FRAME_LIST_SIZE, 1024)]; -/* Queue Element Transfer Descriptor (qTD). Paragraph 3.5 */ +int ehci_iso_urb_init(struct usbh_bus *bus, struct usbh_urb *urb); +void ehci_kill_iso_urb(struct usbh_bus *bus, struct usbh_urb *urb); +void ehci_scan_isochronous_list(struct usbh_bus *bus); -struct ehci_qtd { - uint32_t next_qtd; /* 0x00-0x03: Next qTD Pointer */ - uint32_t alt_next_qtd; /* 0x04-0x07: Alternate Next qTD Pointer */ - uint32_t token; /* 0x08-0x0b: qTD Token */ - uint32_t bpl[5]; /* 0x0c-0x1c: Buffer Page Pointer List */ -}; - -#define SIZEOF_EHCI_QTD (32) /* 8*sizeof(uint32_t) */ - -/* Queue Head. Paragraph 3.6 */ - -struct ehci_qh { - uint32_t hlp; /* 0x00-0x03: Queue Head Horizontal Link Pointer */ - uint32_t epchar; /* 0x04-0x07: Endpoint Characteristics */ - uint32_t epcap; /* 0x08-0x0b: Endpoint Capabilities */ - uint32_t curr_qtd; /* 0x0c-0x0f: Current qTD Pointer */ - struct ehci_qtd overlay; /* 0x10-0x2c: Transfer overlay */ -}; - -#define SIZEOF_EHCI_QH (48) /* 4*sizeof(uint32_t) + 32 */ - -/* Isochronous (High-Speed) Transfer Descriptor (iTD). - * Paragraph 3.3. Must be aligned to 32-byte boundaries. - */ - -struct ehci_itd { - uint32_t nlp; /* 0x00-0x03: Next link pointer */ - uint32_t tscl[8]; /* 0x04-0x23: Transaction Status and Control List */ - uint32_t bpl[7]; /* 0x24-0x3c: Buffer Page Pointer List */ -}; - -#define SIZEOF_EHCI_ITD (64) /* 16*sizeof(uint32_t) */ - -/* Split Transaction Isochronous Transfer Descriptor (siTD). Paragraph 3.4 */ - -struct ehci_sitd { - uint32_t nlp; /* 0x00-0x03: Next link pointer */ - uint32_t epchar; /* 0x04-0x07: Endpoint and Transaction Translator Characteristics */ - uint32_t mfsc; /* 0x08-0x0b: Micro-frame Schedule Control */ - uint32_t tsc; /* 0x0c-0x0f: Transfer Status and Control */ - uint32_t bpl[2]; /* 0x10-0x17: Buffer Pointer List */ - uint32_t blp; /* 0x18-0x1b: Back link pointer */ -}; - -#define SIZEOF_EHCI_SITD (28) /* 7*sizeof(uint32_t) */ - -#endif /* USB_HC_EHCI_H */ +#endif diff --git a/port/ohci/usb_hc_ohci.c b/port/ohci/usb_hc_ohci.c index b3d65829..fda18090 100644 --- a/port/ohci/usb_hc_ohci.c +++ b/port/ohci/usb_hc_ohci.c @@ -3,8 +3,8 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include "usb_ohci_priv.h" -#include "usb_ehci_priv.h" +#include "usb_hc_ohci.h" +#include "usb_hc_ehci.h" int ohci_init(struct usbh_bus *bus) { diff --git a/port/ohci/usb_hc_ohci.h b/port/ohci/usb_hc_ohci.h index 030350e5..68815d9d 100644 --- a/port/ohci/usb_hc_ohci.h +++ b/port/ohci/usb_hc_ohci.h @@ -1,484 +1,24 @@ -/**************************************************************************** - * include/nuttx/usb/ohci.h +/* + * Copyright (c) 2024, sakumisu * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -#ifndef __INCLUDE_NUTTX_USB_OHCI_H -#define __INCLUDE_NUTTX_USB_OHCI_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* Register offsets *********************************************************/ - -/* Control and status registers (section 7.1) */ - -#define OHCI_HCIREV_OFFSET 0x0000 /* HcRevision: Version of HCI specification */ -#define OHCI_CTRL_OFFSET 0x0004 /* HcControl: HC control */ -#define OHCI_CMDST_OFFSET 0x0008 /* HcCommandStatus: HC command status */ -#define OHCI_INTST_OFFSET 0x000c /* HcInterruptStatus: HC interrupt status */ -#define OHCI_INTEN_OFFSET 0x0010 /* HcInterruptEnable: HC interrupt enable */ -#define OHCI_INTDIS_OFFSET 0x0014 /* HcInterruptDisable: HC interrupt disable */ - -/* Memory pointer registers (section 7.2) */ - -#define OHCI_HCCA_OFFSET 0x0018 /* HcHCCA: HC communication area */ -#define OHCI_PERED_OFFSET 0x001c /* HcPeriodCurrentED: Current isoc or int endpoint desc */ -#define OHCI_CTRLHEADED_OFFSET 0x0020 /* HcControlHeadED: First EP desc in the control list */ -#define OHCI_CTRLED_OFFSET 0x0024 /* HcControlCurrentED: Current EP desc in the control list */ -#define OHCI_BULKHEADED_OFFSET 0x0028 /* HcBulkHeadED: First EP desc in the bulk list */ -#define OHCI_BULKED_OFFSET 0x002c /* HcBulkCurrentED: Current EP desc in the bulk list */ -#define OHCI_DONEHEAD_OFFSET 0x0030 /* HcDoneHead: Last transfer desc added to DONE queue */ - -/* Frame counter registers (section 7.3) */ - -#define OHCI_FMINT_OFFSET 0x0034 /* HcFmInterval: Bit time interval that would not cause overrun */ -#define OHCI_FMREM_OFFSET 0x0038 /* HcFmRemaining: Bit time remaining in current frame */ -#define OHCI_FMNO_OFFSET 0x003c /* HcFmNumber: Frame number counter */ -#define OHCI_PERSTART_OFFSET 0x0040 /* HcPeriodicStart: Time to start processing periodic list */ - -/* Root hub registers (section 7.4) */ - -#define OHCI_LSTHRES_OFFSET 0x0044 /* HcLSThreshold: Commit to transfer threshold */ -#define OHCI_RHDESCA_OFFSET 0x0048 /* HcRhDescriptorA: Describes root hub (part A) */ -#define OHCI_RHDESCB_OFFSET 0x004c /* HcRhDescriptorB: Describes root hub (part B) */ -#define OHCI_RHSTATUS_OFFSET 0x0050 /* HcRhStatus: Root hub status */ - -#define OHCI_MAX_RHPORT 15 /* Maximum number of OHCI root hub ports */ - -#define OHCI_RHPORTST_OFFSET(n) (0x0054 + (((n) - 1) << 2)) -#define OHCI_RHPORTST1_OFFSET 0x0054 /* HcRhPort1Status: Root hub port status 1 */ -#define OHCI_RHPORTST2_OFFSET 0x0058 /* HcRhPort2Status: Root hub port status 2 */ -#define OHCI_RHPORTST3_OFFSET 0x005c /* HcRhPort3Status: Root hub port status 3 */ -#define OHCI_RHPORTST4_OFFSET 0x0060 /* HcRhPort4Status: Root hub port status 4 */ -#define OHCI_RHPORTST5_OFFSET 0x0064 /* HcRhPort5Status: Root hub port status 5 */ -#define OHCI_RHPORTST6_OFFSET 0x0068 /* HcRhPort6Status: Root hub port status 6 */ -#define OHCI_RHPORTST7_OFFSET 0x006c /* HcRhPort7Status: Root hub port status 7 */ -#define OHCI_RHPORTST8_OFFSET 0x0070 /* HcRhPort8Status: Root hub port status 8 */ -#define OHCI_RHPORTST9_OFFSET 0x0074 /* HcRhPort9Status: Root hub port status 9 */ -#define OHCI_RHPORTST10_OFFSET 0x0078 /* HcRhPort10Status: Root hub port status 10 */ -#define OHCI_RHPORTST11_OFFSET 0x007c /* HcRhPort11Status: Root hub port status 11 */ -#define OHCI_RHPORTST12_OFFSET 0x0080 /* HcRhPort12Status: Root hub port status 12 */ -#define OHCI_RHPORTST13_OFFSET 0x0084 /* HcRhPort13Status: Root hub port status 13 */ -#define OHCI_RHPORTST14_OFFSET 0x0088 /* HcRhPort14Status: Root hub port status 14 */ -#define OHCI_RHPORTST15_OFFSET 0x008c /* HcRhPort15Status: Root hub port status 15 */ - -/* Register bit definitions *************************************************/ - -/* HcRevision: Version of HCI specification (7.1.1) */ - -#define OHCI_HCIREV_SHIFT (0) /* Bits 0-7: HCI spec version (BCD) */ -#define OHCI_HCIREV_MASK (0xff << OHCI_HCIREV_SHIFT) - -/* HcControl: HC control (7.1.2) */ - -#define OHCI_CTRL_CBSR (3 << 0) /* Bit 0: Control/bulk service ratio */ -#define OHCI_CTRL_PLE (1 << 2) /* Bit 1: Periodic list enable */ -#define OHCI_CTRL_IE (1 << 3) /* Bit 2: Isochronous enable */ -#define OHCI_CTRL_CLE (1 << 4) /* Bit 3: Control list enable */ -#define OHCI_CTRL_BLE (1 << 5) /* Bit 4: Bulk list enable */ -#define OHCI_CTRL_HCFS_SHIFT (6) /* Bits 6-7: Host controller functional state */ -#define OHCI_CTRL_HCFS_MASK (3 << OHCI_CTRL_HCFS_SHIFT) -# define OHCI_CTRL_HCFS_RESET (0 << OHCI_CTRL_HCFS_SHIFT) -# define OHCI_CTRL_HCFS_RESUME (1 << OHCI_CTRL_HCFS_SHIFT) -# define OHCI_CTRL_HCFS_OPER (2 << OHCI_CTRL_HCFS_SHIFT) -# define OHCI_CTRL_HCFS_SUSPEND (3 << OHCI_CTRL_HCFS_SHIFT) -#define OHCI_CTRL_IR (1 << 8) /* Bit 8: Interrupt routing */ -#define OHCI_CTRL_RWC (1 << 9) /* Bit 9: Remote wakeup connected */ -#define OHCI_CTRL_RWE (1 << 10) /* Bit 10: Remote wakeup enable */ - /* Bits 11-31: Reserved */ - -/* HcCommandStatus: HC command status (7.1.3) */ - -#define OHCI_CMDST_HCR (1 << 0) /* Bit 0: Host controller reset */ -#define OHCI_CMDST_CLF (1 << 1) /* Bit 1: Control list filled */ -#define OHCI_CMDST_BLF (1 << 2) /* Bit 2: Bulk list filled */ -#define OHCI_CMDST_OCR (1 << 3) /* Bit 3: Ownership change request */ - /* Bits 4-15: Reserved */ -#define OHCI_CMDST_SOC (3 << 16) /* Bit 16: Scheduling overrun count */ - /* Bits 17-31: Reserved */ - -/* HcInterruptStatus: HC interrupt status (7.1.4), - * HcInterruptEnable: HC interrupt enable (7.1.5), and - * HcInterruptDisable: HC interrupt disable (7.1.6) + * SPDX-License-Identifier: Apache-2.0 */ +#ifndef _USB_OHCI_PRIV_H +#define _USB_OHCI_PRIV_H -#define OHCI_INT_SO (1 << 0) /* Bit 0: Scheduling overrun */ -#define OHCI_INT_WDH (1 << 1) /* Bit 1: Writeback done head */ -#define OHCI_INT_SF (1 << 2) /* Bit 2: Start of frame */ -#define OHCI_INT_RD (1 << 3) /* Bit 3: Resume detected */ -#define OHCI_INT_UE (1 << 4) /* Bit 4: Unrecoverable error */ -#define OHCI_INT_FNO (1 << 5) /* Bit 5: Frame number overflow */ -#define OHCI_INT_RHSC (1 << 6) /* Bit 6: Root hub status change */ - /* Bits 7-29: Reserved */ -#define OHCI_INT_OC (1 << 30) /* Bit 30: Ownership change */ -#define OHCI_INT_MIE (1 << 31) /* Bit 31: Master interrupt enable - * (Enable/disable only) */ +#include "usbh_core.h" +#include "usbh_hub.h" +#include "usb_ohci_reg.h" -/* HcHCCA: HC communication area (7.2.1): - * - * 32-bits aligned to 256 byte boundary. - */ +#define OHCI_HCOR ((struct ohci_hcor *)(uintptr_t)(bus->hcd.reg_base + CONFIG_USB_OHCI_HCOR_OFFSET)) -/* HcPeriodCurrentED: Current isoc or int endpoint desc (7.2.2), - * HcControlHeadED: First EP desc in the control list (7.2.3), - * HcControlCurrentED: Current EP desc in the control list (7.2.4), - * HcBulkHeadED: First EP desc in the bulk list (7.2.5), - * HcBulkCurrentED: Current EP desc in the bulk list (7.2.6), and - * HcDoneHead: Last transfer desc added to DONE queue (7.2.7): - * - * All 32-bits aligned to an 8-byte boundary - */ +int ohci_init(struct usbh_bus *bus); +int ohci_deinit(struct usbh_bus *bus); +uint16_t ohci_get_frame_number(struct usbh_bus *bus); +int ohci_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, uint8_t *buf); +int ohci_submit_urb(struct usbh_urb *urb); +int ohci_kill_urb(struct usbh_urb *urb); -/* HcFmInterval: Bit time interval that would not cause overrun (7.3.1) */ +void OHCI_IRQHandler(uint8_t busid); -#define OHCI_FMINT_FI_SHIFT (0) /* Bits 0-13: Frame interval */ -#define OHCI_FMINT_FI_MASK (0x3fff << OHCI_FMINT_FI_SHIFT) - /* Bits 14-15: Reserved */ -#define OHCI_FMINT_FSMPS_SHIFT (16) /* Bits 16-30: FS largest packet data */ -#define OHCI_FMINT_FSMPS_MASK (0x7fff << OHCI_FMINT_FSMPS_SHIFT) -#define OHCI_FMINT_FIT (1 << 31) /* Bit 31: Frame interval toggle */ - -/* HcFmRemaining: Bit time remaining in current frame (7.3.2) */ - -#define OHCI_FMREM_FR_SHIFT (0) /* Bits 0-13: Frame remaining */ -#define OHCI_FMREM_FR_MASK (0x3fff << OHCI_FMREM_FR_SHIFT) - /* Bits 16-30: Reserved */ -#define OHCI_FMINT_FRT (1 << 31) /* Bit 31: Frame remaining toggle */ - -/* HcFmNumber: Frame number counter (7.3.3) */ - -#define OHCI_FMNO_FI_SHIFT (0) /* Bits 0-15: Frame number */ -#define OHCI_FMNO_FI_MASK (0xffff << OHCI_FMINT_FI_SHIFT) - /* Bits 16-31: Reserved */ - -/* HcPeriodicStart: Time to start processing periodic list (7.3.4) */ - -#define OHCI_PERSTART_SHIFT (0) /* Bits 0-13: Periodic start */ -#define OHCI_PERSTART_MASK (0x3fff << OHCI_PERSTART_SHIFT) - /* Bits 14-31: Reserved */ - -/* HcLSThreshold: Commit to transfer threshold (7.3.5) */ - -#define OHCI_LSTHRES_SHIFT (0) /* Bits 0-11: LS threshold */ -#define OHCI_LSTHRES_MASK (0x0fff << OHCI_PERSTART_SHIFT) - /* Bits 12-31: Reserved */ - -/* HcRhDescriptorN: Describes root hub (part A) (7.4.1) */ - -#define OHCI_RHDESCA_NDP_SHIFT (0) /* Bits 0-7: Number downstream ports */ -#define OHCI_RHDESCA_NDP_MASK (0xff << OHCI_RHDESCA_NDP_SHIFT) -#define OHCI_RHDESCA_PSM (1 << 8) /* Bit 8: Power switching mode */ -#define OHCI_RHDESCA_NPS (1 << 9) /* Bit 9: No power switching */ -#define OHCI_RHDESCA_DT (1 << 10) /* Bit 10: Device type */ -#define OHCI_RHDESCA_OCPM (1 << 11) /* Bit 11: Over current protection mode */ -#define OHCI_RHDESCA_NOCP (1 << 12) /* Bit 12: No over current protection */ - /* Bits 13-23: Reserved */ -#define OHCI_RHDESCA_POTPGT_SHIFT (24) /* Bits 24-31: Power on to power good time */ -#define OHCI_RHDESCA_POTPGT_MASK (0xff << OHCI_RHDESCA_POTPGT_SHIFT) - -/* HcRhDescriptorB: Describes root hub (part B) (7.4.2) */ - -#define OHCI_RHDESCB_DR_SHIFT (0) /* Bits 0-15: Device removable */ -#define OHCI_RHDESCB_DR_MASK (0xffff << OHCI_RHDESCB_DR_SHIFT) -# define OHCI_RHDESCB_ATTACHED(n) (1 << (OHCI_RHDESCB_DR_SHIFT+(n))) -#define OHCI_RHDESCB_PPCM_SHIFT (16) /* Bits 16-31: Port power control mask */ -#define OHCI_RHDESCB_PPCM_MASK (0xffff << OHCI_RHDESCB_PPCM_SHIFT) -# define OHCI_RHDESCB_POWERED(n) (1 << (OHCI_RHDESCB_DR_SHIFT+(n))) - -/* HcRhStatus: Root hub status (7.4.3) */ - -#define OHCI_RHSTATUS_LPS (1 << 0) /* Bit 0: Local power status (read)*/ -#define OHCI_RHSTATUS_CGP (1 << 0) /* Bit 0: Clear global power (write)*/ -#define OHCI_RHSTATUS_OCI (1 << 1) /* Bit 1: Over current indicator */ - /* Bits 2-14: Reserved */ -#define OHCI_RHSTATUS_DRWE (1 << 15) /* Bit 15: Device remote wakeup enable */ -#define OHCI_RHSTATUS_LPSC (1 << 16) /* Bit 16: Local power status change (read) */ -#define OHCI_RHSTATUS_SGP (1 << 16) /* Bit 16: Set global power (write) */ -#define OHCI_RHSTATUS_OCIC (1 << 17) /* Bit 17: Overcurrent indicator change */ - /* Bits 18-30: Reserved */ -#define OHCI_RHSTATUS_CRWE (1 << 31) /* Bit 31: Clear remote wakeup enable */ - -/* HcRhPortStatus: Root hub port status (7.4.4) */ - -#define OHCI_RHPORTST_CCS (1 << 0) /* Bit 0: Current connect status */ -#define OHCI_RHPORTST_PES (1 << 1) /* Bit 1: Port enable status */ -#define OHCI_RHPORTST_PSS (1 << 2) /* Bit 2: Port suspend status */ -#define OHCI_RHPORTST_POCI (1 << 3) /* Bit 3: Port over current indicator */ -#define OHCI_RHPORTST_PRS (1 << 4) /* Bit 4: Port reset status */ - /* Bits 5-7: Reserved */ -#define OHCI_RHPORTST_PPS (1 << 8) /* Bit 8: Port power status */ -#define OHCI_RHPORTST_LSDA (1 << 9) /* Bit 9: Low speed device attached */ - /* Bits 10-15: Reserved */ -#define OHCI_RHPORTST_CSC (1 << 16) /* Bit 16: Connect status change */ -#define OHCI_RHPORTST_PESC (1 << 17) /* Bit 17: Port enable status change */ -#define OHCI_RHPORTST_PSSC (1 << 18) /* Bit 18: Port suspend status change */ -#define OHCI_RHPORTST_OCIC (1 << 19) /* Bit 19: Port over current indicator change */ -#define OHCI_RHPORTST_PRSC (1 << 20) /* Bit 20: Port reset status change */ - /* Bits 21-31: Reserved */ - -/* Transfer Descriptors *****************************************************/ - -/* Endpoint Descriptor Offsets (4.2.1) */ - -#define ED_CONTROL_OFFSET (0x00) /* ED status/control bits */ -#define ED_TAILP_OFFSET (0x04) /* TD Queue Tail Pointer (TailP) */ -#define ED_HEADP_OFFSET (0x08) /* TD Queue Head Pointer (HeadP) */ -#define ED_NEXTED_OFFSET (0x0c) /* Next Endpoint Descriptor (NextED) */ - -/* Endpoint Descriptor Bit Definitions (4.2.2) */ - -#define ED_CONTROL_FA_SHIFT (0) /* Bits 0-6: Function Address */ -#define ED_CONTROL_FA_MASK (0x7f << ED_CONTROL_FA_SHIFT) -#define ED_CONTROL_EN_SHIFT (7) /* Bits 7-10: Endpoint number */ -#define ED_CONTROL_EN_MASK (15 << ED_CONTROL_EN_SHIFT) -#define ED_CONTROL_D_SHIFT (11) /* Bits 11-12: Direction */ -#define ED_CONTROL_D_MASK (3 << ED_CONTROL_D_SHIFT) -# define ED_CONTROL_D_TD1 (0 << ED_CONTROL_D_SHIFT) /* Get direction from TD */ -# define ED_CONTROL_D_OUT (1 << ED_CONTROL_D_SHIFT) /* OUT */ -# define ED_CONTROL_D_IN (2 << ED_CONTROL_D_SHIFT) /* IN */ -# define ED_CONTROL_D_TD2 (3 << ED_CONTROL_D_SHIFT) /* Get direction from TD */ - -#define ED_CONTROL_S (1 << 13) /* Bit 13: Speed (low) */ -#define ED_CONTROL_K (1 << 14) /* Bit 14: Skip */ -#define ED_CONTROL_F (1 << 15) /* Bit 15: Format (isochronous) */ -#define ED_CONTROL_MPS_SHIFT (16) /* Bits 16-26: Maximum packet size */ -#define ED_CONTROL_MPS_MASK (0x7ff << ED_CONTROL_MPS_SHIFT) - -#define ED_HEADP_ADDR_SHIFT (0) -#define ED_HEADP_ADDR_MASK 0xfffffff0 -#define ED_HEADP_H (1 << 0) /* Bit 0: Halted */ -#define ED_HEADP_C (1 << 1) /* Bit 1: Toggle carry */ - -/* General Transfer Descriptor Offsets (4.3.1) */ - -#define GTD_STATUS_OFFSET (0x00) /* TD status bits */ -#define GTD_CBP_OFFSET (0x04) /* Current Buffer Pointer (CBP) */ -#define GTD_NEXTTD_OFFSET (0x08) /* Next TD (NextTD) */ -#define GTD_BE_OFFSET (0x0c) /* Buffer End (BE) */ - -/* General Transfer Descriptor Bit Definitions */ - - /* Bits 0-17: Reserved */ - -#define GTD_STATUS_R (1 << 18) /* Bit 18: Buffer rounding */ -#define GTD_STATUS_DP_SHIFT (19) /* Bits 19-20: Direction/PID */ -#define GTD_STATUS_DP_MASK (3 << GTD_STATUS_DP_SHIFT) -# define GTD_STATUS_DP_SETUP (0 << GTD_STATUS_DP_SHIFT) /* To endpoint */ -# define GTD_STATUS_DP_OUT (1 << GTD_STATUS_DP_SHIFT) /* To endpoint */ -# define GTD_STATUS_DP_IN (2 << GTD_STATUS_DP_SHIFT) /* From endpoint */ - -#define GTD_STATUS_DI_SHIFT (21) /* Bits 21-23: Delay input */ -#define GTD_STATUS_DI_MASK (7 << GTD_STATUS_DI_SHIFT) -#define GTD_STATUS_T_SHIFT (24) /* Bits 24-25: Data Toggle */ -#define GTD_STATUS_T_MASK (3 << GTD_STATUS_T_SHIFT) -# define GTD_STATUS_T_TOGGLE (0 << GTD_STATUS_T_SHIFT) -# define GTD_STATUS_T_DATA0 (2 << GTD_STATUS_T_SHIFT) -# define GTD_STATUS_T_DATA1 (3 << GTD_STATUS_T_SHIFT) -#define GTD_STATUS_EC_SHIFT (26) /* Bits 26-27: Error count */ -#define GTD_STATUS_EC_MASK (3 << GTD_STATUS_EC_SHIFT) -#define GTD_STATUS_CC_SHIFT (28) /* Bits 28-31: Condition code */ -#define GTD_STATUS_CC_MASK (15 << GTD_STATUS_CC_SHIFT) - -/* Isochronous Transfer Descriptor Offsets (4.3.2) */ - -#define ITD_STATUS_OFFSET (0x00) /* TD status bits */ -#define ITD_BP0_OFFSET (0x04) /* Buffer page 0 (BP0) */ -#define ITD_NEXTTD_OFFSET (0x08) /* Next TD (NextTD) */ -#define ITD_BE_OFFSET (0x0c) /* Buffer End (BE) */ - -#define ITD_NPSW (8) -#define ITD_PSW0_OFFSET (0x10) /* Offset0/PSW0 */ -#define ITD_PSW1_OFFSET (0x12) /* Offset1/PSW1 */ -#define ITD_PSW2_OFFSET (0x14) /* Offset2/PSW2 */ -#define ITD_PSW3_OFFSET (0x16) /* Offset3/PSW3 */ -#define ITD_PSW4_OFFSET (0x18) /* Offset4/PSW4 */ -#define ITD_PSW5_OFFSET (0x1a) /* Offset5/PSW5 */ -#define ITD_PSW6_OFFSET (0x1c) /* Offset6/PSW6 */ -#define ITD_PSW7_OFFSET (0x1e) /* Offset7/PSW7 */ - -/* Condition codes (Table 4-7) */ - -#define TD_CC_NOERROR 0x00 -#define TD_CC_CRC 0x01 -#define TD_CC_BITSTUFFING 0x02 -#define TD_CC_DATATOGGLEMISMATCH 0x03 -#define TD_CC_STALL 0x04 -#define TD_CC_DEVNOTRESPONDING 0x05 -#define TD_CC_PIDCHECKFAILURE 0x06 -#define TD_CC_UNEXPECTEDPID 0x07 -#define TD_CC_DATAOVERRUN 0x08 -#define TD_CC_DATAUNDERRUN 0x09 -#define TD_CC_BUFFEROVERRUN 0x0c -#define TD_CC_BUFFERUNDERRUN 0x0d -#define TD_CC_NOTACCESSED 0x0f - -#define TD_CC_USER 0x10 /* For use by OHCI drivers */ - -/* Host Controller Communications Area Format (4.4.1) ***********************/ - -/* HccaInterruptTable: 32x32-bit pointers to interrupt EDs */ - -#define HCCA_INTTBL_OFFSET (0x00) -#define HCCA_INTTBL_WSIZE (32) -#define HCCA_INTTBL_BSIZE (HCCA_INTTBL_WSIZE * 4) - -/* HccaFrameNumber: Current frame number */ - -#define HCCA_FMNO_OFFSET (0x80) -#define HCCA_FMNO_BSIZE (2) - -/* HccaPad1: Zero when frame no. updated */ - -#define HCCA_PAD1_OFFSET (0x82) -#define HCCA_PAD1_BSIZE (2) - -/* HccaDoneHead: When the HC reaches the end of a frame and its deferred - * interrupt register is 0, it writes the current value of its HcDoneHead to - * this location and generates an interrupt. - * - * The LSB of HCCADoneHead may be set to 1 to indicate that an unmasked - * HcInterruptStatus was set when HccaDoneHead was written. - */ - -#define HCCA_DONEHEAD_OFFSET (0x84) -#define HCCA_DONEHEAD_BSIZE (4) - -#define HCCA_DONEHEAD_MASK 0xfffffffe -#define HCCA_DONEHEAD_INTSTA (1 << 0) - -/* 0x88: 116 bytes reserved */ - -#define HCCA_RESERVED_OFFSET (0x88) -#define HCCA_RESERVED_BSIZE (116) - -/**************************************************************************** - * Public Types - ****************************************************************************/ - -struct ohci_hcor -{ - volatile uint32_t hcrevision; /* 0x00 */ - volatile uint32_t hccontrol; /* 0x04 */ - volatile uint32_t hccmdsts; /* 0x08 */ - volatile uint32_t hcintsts; /* 0x0c */ - volatile uint32_t hcinten; /* 0x10 */ - volatile uint32_t hcintdis; /* 0x14 */ - volatile uint32_t hchcca; /* 0x18 */ - volatile uint32_t hcperiodcurrented; /* 0x1c */ - volatile uint32_t hccontrolheaded; /* 0x20 */ - volatile uint32_t hccontrolcurrented; /* 0x24 */ - volatile uint32_t hcbulkheaded; /* 0x28 */ - volatile uint32_t hcbulkcurrented; /* 0x2c */ - volatile uint32_t hcdonehead; /* 0x30 */ - volatile uint32_t hcfminterval; /* 0x34 */ - volatile uint32_t hcfmremaining; /* 0x38 */ - volatile uint32_t hcfmnumber; /* 0x3c */ - volatile uint32_t hcperiodicstart; /* 0x40 */ - volatile uint32_t hclsthreshold; /* 0x44 */ - volatile uint32_t hcrhdescriptora; /* 0x48 */ - volatile uint32_t hcrhdescriptorb; /* 0x4c */ - volatile uint32_t hcrhsts; /* 0x50 */ - volatile uint32_t hcrhportsts[15]; /* 0x54 */ -}; - -/* Endpoint Descriptor Offsets (4.2.1) */ - -struct ohci_ed_s -{ - volatile uint32_t ctrl; /* ED status/control bits */ - volatile uint32_t tailp; /* TD Queue Tail Pointer (TailP) */ - volatile uint32_t headp; /* TD Queue Head Pointer (HeadP) */ - volatile uint32_t nexted; /* Next Endpoint Descriptor (NextED) */ -}; - -/* General Transfer Descriptor (4.3.1) */ - -struct ohci_gtd_s -{ - volatile uint32_t ctrl; /* TD status/control bits */ - volatile uint32_t cbp; /* Current Buffer Pointer (CBP) */ - volatile uint32_t nexttd; /* Next TD (NextTD) */ - volatile uint32_t be; /* Buffer End (BE) */ -}; - -/* Isochronous Transfer Descriptor Offsets (4.3.2) */ - -struct ohci_itd_s -{ - volatile uint32_t ctrl; /* TD status/control bits */ - volatile uint32_t bp0; /* Buffer page 0 (BP0 */ - volatile uint32_t nexttd; /* Next TD (NextTD) */ - volatile uint32_t be; /* Buffer End (BE) */ - volatile uint16_t psw[ITD_NPSW]; /* Offset/PSW */ -}; - -/* Host Controller Communications Area Format (4.4.1) */ - -struct ohci_hcca_s -{ - /* HccaInterruptTable: 32x32-bit pointers to interrupt EDs */ - - volatile uint32_t inttbl[HCCA_INTTBL_WSIZE]; - - /* HccaFrameNumber: Current frame number and - * HccaPad1: Zero when frame no. updated - */ - - volatile uint16_t fmno; - volatile uint16_t pad1; - - /* HccaDoneHead: When the HC reaches the end of a frame and its deferred - * interrupt register is 0, it writes the current value of its HcDoneHead - * to this location and generates an interrupt. - */ - - volatile uint32_t donehead; - volatile uint8_t reserved[HCCA_RESERVED_BSIZE]; - volatile uint32_t extra; -} __attribute__((aligned(256))); - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -#ifdef __cplusplus -#define EXTERN extern "C" -extern "C" -{ -#else -#define EXTERN extern -#endif - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - -#undef EXTERN -#ifdef __cplusplus -} -#endif - -#endif /* __INCLUDE_NUTTX_USB_OHCI_H */ +#endif \ No newline at end of file diff --git a/port/ohci/usb_ohci_priv.h b/port/ohci/usb_ohci_priv.h deleted file mode 100644 index 4404dc25..00000000 --- a/port/ohci/usb_ohci_priv.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef _USB_OHCI_PRIV_H -#define _USB_OHCI_PRIV_H - -#include "usbh_core.h" -#include "usbh_hub.h" -#include "usb_hc_ohci.h" - -#define OHCI_HCOR ((struct ohci_hcor *)(uintptr_t)(bus->hcd.reg_base + CONFIG_USB_OHCI_HCOR_OFFSET)) - -int ohci_init(struct usbh_bus *bus); -int ohci_deinit(struct usbh_bus *bus); -uint16_t ohci_get_frame_number(struct usbh_bus *bus); -int ohci_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, uint8_t *buf); -int ohci_submit_urb(struct usbh_urb *urb); -int ohci_kill_urb(struct usbh_urb *urb); - -void OHCI_IRQHandler(uint8_t busid); - -#endif \ No newline at end of file diff --git a/port/ohci/usb_ohci_reg.h b/port/ohci/usb_ohci_reg.h new file mode 100644 index 00000000..030350e5 --- /dev/null +++ b/port/ohci/usb_ohci_reg.h @@ -0,0 +1,484 @@ +/**************************************************************************** + * include/nuttx/usb/ohci.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __INCLUDE_NUTTX_USB_OHCI_H +#define __INCLUDE_NUTTX_USB_OHCI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register offsets *********************************************************/ + +/* Control and status registers (section 7.1) */ + +#define OHCI_HCIREV_OFFSET 0x0000 /* HcRevision: Version of HCI specification */ +#define OHCI_CTRL_OFFSET 0x0004 /* HcControl: HC control */ +#define OHCI_CMDST_OFFSET 0x0008 /* HcCommandStatus: HC command status */ +#define OHCI_INTST_OFFSET 0x000c /* HcInterruptStatus: HC interrupt status */ +#define OHCI_INTEN_OFFSET 0x0010 /* HcInterruptEnable: HC interrupt enable */ +#define OHCI_INTDIS_OFFSET 0x0014 /* HcInterruptDisable: HC interrupt disable */ + +/* Memory pointer registers (section 7.2) */ + +#define OHCI_HCCA_OFFSET 0x0018 /* HcHCCA: HC communication area */ +#define OHCI_PERED_OFFSET 0x001c /* HcPeriodCurrentED: Current isoc or int endpoint desc */ +#define OHCI_CTRLHEADED_OFFSET 0x0020 /* HcControlHeadED: First EP desc in the control list */ +#define OHCI_CTRLED_OFFSET 0x0024 /* HcControlCurrentED: Current EP desc in the control list */ +#define OHCI_BULKHEADED_OFFSET 0x0028 /* HcBulkHeadED: First EP desc in the bulk list */ +#define OHCI_BULKED_OFFSET 0x002c /* HcBulkCurrentED: Current EP desc in the bulk list */ +#define OHCI_DONEHEAD_OFFSET 0x0030 /* HcDoneHead: Last transfer desc added to DONE queue */ + +/* Frame counter registers (section 7.3) */ + +#define OHCI_FMINT_OFFSET 0x0034 /* HcFmInterval: Bit time interval that would not cause overrun */ +#define OHCI_FMREM_OFFSET 0x0038 /* HcFmRemaining: Bit time remaining in current frame */ +#define OHCI_FMNO_OFFSET 0x003c /* HcFmNumber: Frame number counter */ +#define OHCI_PERSTART_OFFSET 0x0040 /* HcPeriodicStart: Time to start processing periodic list */ + +/* Root hub registers (section 7.4) */ + +#define OHCI_LSTHRES_OFFSET 0x0044 /* HcLSThreshold: Commit to transfer threshold */ +#define OHCI_RHDESCA_OFFSET 0x0048 /* HcRhDescriptorA: Describes root hub (part A) */ +#define OHCI_RHDESCB_OFFSET 0x004c /* HcRhDescriptorB: Describes root hub (part B) */ +#define OHCI_RHSTATUS_OFFSET 0x0050 /* HcRhStatus: Root hub status */ + +#define OHCI_MAX_RHPORT 15 /* Maximum number of OHCI root hub ports */ + +#define OHCI_RHPORTST_OFFSET(n) (0x0054 + (((n) - 1) << 2)) +#define OHCI_RHPORTST1_OFFSET 0x0054 /* HcRhPort1Status: Root hub port status 1 */ +#define OHCI_RHPORTST2_OFFSET 0x0058 /* HcRhPort2Status: Root hub port status 2 */ +#define OHCI_RHPORTST3_OFFSET 0x005c /* HcRhPort3Status: Root hub port status 3 */ +#define OHCI_RHPORTST4_OFFSET 0x0060 /* HcRhPort4Status: Root hub port status 4 */ +#define OHCI_RHPORTST5_OFFSET 0x0064 /* HcRhPort5Status: Root hub port status 5 */ +#define OHCI_RHPORTST6_OFFSET 0x0068 /* HcRhPort6Status: Root hub port status 6 */ +#define OHCI_RHPORTST7_OFFSET 0x006c /* HcRhPort7Status: Root hub port status 7 */ +#define OHCI_RHPORTST8_OFFSET 0x0070 /* HcRhPort8Status: Root hub port status 8 */ +#define OHCI_RHPORTST9_OFFSET 0x0074 /* HcRhPort9Status: Root hub port status 9 */ +#define OHCI_RHPORTST10_OFFSET 0x0078 /* HcRhPort10Status: Root hub port status 10 */ +#define OHCI_RHPORTST11_OFFSET 0x007c /* HcRhPort11Status: Root hub port status 11 */ +#define OHCI_RHPORTST12_OFFSET 0x0080 /* HcRhPort12Status: Root hub port status 12 */ +#define OHCI_RHPORTST13_OFFSET 0x0084 /* HcRhPort13Status: Root hub port status 13 */ +#define OHCI_RHPORTST14_OFFSET 0x0088 /* HcRhPort14Status: Root hub port status 14 */ +#define OHCI_RHPORTST15_OFFSET 0x008c /* HcRhPort15Status: Root hub port status 15 */ + +/* Register bit definitions *************************************************/ + +/* HcRevision: Version of HCI specification (7.1.1) */ + +#define OHCI_HCIREV_SHIFT (0) /* Bits 0-7: HCI spec version (BCD) */ +#define OHCI_HCIREV_MASK (0xff << OHCI_HCIREV_SHIFT) + +/* HcControl: HC control (7.1.2) */ + +#define OHCI_CTRL_CBSR (3 << 0) /* Bit 0: Control/bulk service ratio */ +#define OHCI_CTRL_PLE (1 << 2) /* Bit 1: Periodic list enable */ +#define OHCI_CTRL_IE (1 << 3) /* Bit 2: Isochronous enable */ +#define OHCI_CTRL_CLE (1 << 4) /* Bit 3: Control list enable */ +#define OHCI_CTRL_BLE (1 << 5) /* Bit 4: Bulk list enable */ +#define OHCI_CTRL_HCFS_SHIFT (6) /* Bits 6-7: Host controller functional state */ +#define OHCI_CTRL_HCFS_MASK (3 << OHCI_CTRL_HCFS_SHIFT) +# define OHCI_CTRL_HCFS_RESET (0 << OHCI_CTRL_HCFS_SHIFT) +# define OHCI_CTRL_HCFS_RESUME (1 << OHCI_CTRL_HCFS_SHIFT) +# define OHCI_CTRL_HCFS_OPER (2 << OHCI_CTRL_HCFS_SHIFT) +# define OHCI_CTRL_HCFS_SUSPEND (3 << OHCI_CTRL_HCFS_SHIFT) +#define OHCI_CTRL_IR (1 << 8) /* Bit 8: Interrupt routing */ +#define OHCI_CTRL_RWC (1 << 9) /* Bit 9: Remote wakeup connected */ +#define OHCI_CTRL_RWE (1 << 10) /* Bit 10: Remote wakeup enable */ + /* Bits 11-31: Reserved */ + +/* HcCommandStatus: HC command status (7.1.3) */ + +#define OHCI_CMDST_HCR (1 << 0) /* Bit 0: Host controller reset */ +#define OHCI_CMDST_CLF (1 << 1) /* Bit 1: Control list filled */ +#define OHCI_CMDST_BLF (1 << 2) /* Bit 2: Bulk list filled */ +#define OHCI_CMDST_OCR (1 << 3) /* Bit 3: Ownership change request */ + /* Bits 4-15: Reserved */ +#define OHCI_CMDST_SOC (3 << 16) /* Bit 16: Scheduling overrun count */ + /* Bits 17-31: Reserved */ + +/* HcInterruptStatus: HC interrupt status (7.1.4), + * HcInterruptEnable: HC interrupt enable (7.1.5), and + * HcInterruptDisable: HC interrupt disable (7.1.6) + */ + +#define OHCI_INT_SO (1 << 0) /* Bit 0: Scheduling overrun */ +#define OHCI_INT_WDH (1 << 1) /* Bit 1: Writeback done head */ +#define OHCI_INT_SF (1 << 2) /* Bit 2: Start of frame */ +#define OHCI_INT_RD (1 << 3) /* Bit 3: Resume detected */ +#define OHCI_INT_UE (1 << 4) /* Bit 4: Unrecoverable error */ +#define OHCI_INT_FNO (1 << 5) /* Bit 5: Frame number overflow */ +#define OHCI_INT_RHSC (1 << 6) /* Bit 6: Root hub status change */ + /* Bits 7-29: Reserved */ +#define OHCI_INT_OC (1 << 30) /* Bit 30: Ownership change */ +#define OHCI_INT_MIE (1 << 31) /* Bit 31: Master interrupt enable + * (Enable/disable only) */ + +/* HcHCCA: HC communication area (7.2.1): + * + * 32-bits aligned to 256 byte boundary. + */ + +/* HcPeriodCurrentED: Current isoc or int endpoint desc (7.2.2), + * HcControlHeadED: First EP desc in the control list (7.2.3), + * HcControlCurrentED: Current EP desc in the control list (7.2.4), + * HcBulkHeadED: First EP desc in the bulk list (7.2.5), + * HcBulkCurrentED: Current EP desc in the bulk list (7.2.6), and + * HcDoneHead: Last transfer desc added to DONE queue (7.2.7): + * + * All 32-bits aligned to an 8-byte boundary + */ + +/* HcFmInterval: Bit time interval that would not cause overrun (7.3.1) */ + +#define OHCI_FMINT_FI_SHIFT (0) /* Bits 0-13: Frame interval */ +#define OHCI_FMINT_FI_MASK (0x3fff << OHCI_FMINT_FI_SHIFT) + /* Bits 14-15: Reserved */ +#define OHCI_FMINT_FSMPS_SHIFT (16) /* Bits 16-30: FS largest packet data */ +#define OHCI_FMINT_FSMPS_MASK (0x7fff << OHCI_FMINT_FSMPS_SHIFT) +#define OHCI_FMINT_FIT (1 << 31) /* Bit 31: Frame interval toggle */ + +/* HcFmRemaining: Bit time remaining in current frame (7.3.2) */ + +#define OHCI_FMREM_FR_SHIFT (0) /* Bits 0-13: Frame remaining */ +#define OHCI_FMREM_FR_MASK (0x3fff << OHCI_FMREM_FR_SHIFT) + /* Bits 16-30: Reserved */ +#define OHCI_FMINT_FRT (1 << 31) /* Bit 31: Frame remaining toggle */ + +/* HcFmNumber: Frame number counter (7.3.3) */ + +#define OHCI_FMNO_FI_SHIFT (0) /* Bits 0-15: Frame number */ +#define OHCI_FMNO_FI_MASK (0xffff << OHCI_FMINT_FI_SHIFT) + /* Bits 16-31: Reserved */ + +/* HcPeriodicStart: Time to start processing periodic list (7.3.4) */ + +#define OHCI_PERSTART_SHIFT (0) /* Bits 0-13: Periodic start */ +#define OHCI_PERSTART_MASK (0x3fff << OHCI_PERSTART_SHIFT) + /* Bits 14-31: Reserved */ + +/* HcLSThreshold: Commit to transfer threshold (7.3.5) */ + +#define OHCI_LSTHRES_SHIFT (0) /* Bits 0-11: LS threshold */ +#define OHCI_LSTHRES_MASK (0x0fff << OHCI_PERSTART_SHIFT) + /* Bits 12-31: Reserved */ + +/* HcRhDescriptorN: Describes root hub (part A) (7.4.1) */ + +#define OHCI_RHDESCA_NDP_SHIFT (0) /* Bits 0-7: Number downstream ports */ +#define OHCI_RHDESCA_NDP_MASK (0xff << OHCI_RHDESCA_NDP_SHIFT) +#define OHCI_RHDESCA_PSM (1 << 8) /* Bit 8: Power switching mode */ +#define OHCI_RHDESCA_NPS (1 << 9) /* Bit 9: No power switching */ +#define OHCI_RHDESCA_DT (1 << 10) /* Bit 10: Device type */ +#define OHCI_RHDESCA_OCPM (1 << 11) /* Bit 11: Over current protection mode */ +#define OHCI_RHDESCA_NOCP (1 << 12) /* Bit 12: No over current protection */ + /* Bits 13-23: Reserved */ +#define OHCI_RHDESCA_POTPGT_SHIFT (24) /* Bits 24-31: Power on to power good time */ +#define OHCI_RHDESCA_POTPGT_MASK (0xff << OHCI_RHDESCA_POTPGT_SHIFT) + +/* HcRhDescriptorB: Describes root hub (part B) (7.4.2) */ + +#define OHCI_RHDESCB_DR_SHIFT (0) /* Bits 0-15: Device removable */ +#define OHCI_RHDESCB_DR_MASK (0xffff << OHCI_RHDESCB_DR_SHIFT) +# define OHCI_RHDESCB_ATTACHED(n) (1 << (OHCI_RHDESCB_DR_SHIFT+(n))) +#define OHCI_RHDESCB_PPCM_SHIFT (16) /* Bits 16-31: Port power control mask */ +#define OHCI_RHDESCB_PPCM_MASK (0xffff << OHCI_RHDESCB_PPCM_SHIFT) +# define OHCI_RHDESCB_POWERED(n) (1 << (OHCI_RHDESCB_DR_SHIFT+(n))) + +/* HcRhStatus: Root hub status (7.4.3) */ + +#define OHCI_RHSTATUS_LPS (1 << 0) /* Bit 0: Local power status (read)*/ +#define OHCI_RHSTATUS_CGP (1 << 0) /* Bit 0: Clear global power (write)*/ +#define OHCI_RHSTATUS_OCI (1 << 1) /* Bit 1: Over current indicator */ + /* Bits 2-14: Reserved */ +#define OHCI_RHSTATUS_DRWE (1 << 15) /* Bit 15: Device remote wakeup enable */ +#define OHCI_RHSTATUS_LPSC (1 << 16) /* Bit 16: Local power status change (read) */ +#define OHCI_RHSTATUS_SGP (1 << 16) /* Bit 16: Set global power (write) */ +#define OHCI_RHSTATUS_OCIC (1 << 17) /* Bit 17: Overcurrent indicator change */ + /* Bits 18-30: Reserved */ +#define OHCI_RHSTATUS_CRWE (1 << 31) /* Bit 31: Clear remote wakeup enable */ + +/* HcRhPortStatus: Root hub port status (7.4.4) */ + +#define OHCI_RHPORTST_CCS (1 << 0) /* Bit 0: Current connect status */ +#define OHCI_RHPORTST_PES (1 << 1) /* Bit 1: Port enable status */ +#define OHCI_RHPORTST_PSS (1 << 2) /* Bit 2: Port suspend status */ +#define OHCI_RHPORTST_POCI (1 << 3) /* Bit 3: Port over current indicator */ +#define OHCI_RHPORTST_PRS (1 << 4) /* Bit 4: Port reset status */ + /* Bits 5-7: Reserved */ +#define OHCI_RHPORTST_PPS (1 << 8) /* Bit 8: Port power status */ +#define OHCI_RHPORTST_LSDA (1 << 9) /* Bit 9: Low speed device attached */ + /* Bits 10-15: Reserved */ +#define OHCI_RHPORTST_CSC (1 << 16) /* Bit 16: Connect status change */ +#define OHCI_RHPORTST_PESC (1 << 17) /* Bit 17: Port enable status change */ +#define OHCI_RHPORTST_PSSC (1 << 18) /* Bit 18: Port suspend status change */ +#define OHCI_RHPORTST_OCIC (1 << 19) /* Bit 19: Port over current indicator change */ +#define OHCI_RHPORTST_PRSC (1 << 20) /* Bit 20: Port reset status change */ + /* Bits 21-31: Reserved */ + +/* Transfer Descriptors *****************************************************/ + +/* Endpoint Descriptor Offsets (4.2.1) */ + +#define ED_CONTROL_OFFSET (0x00) /* ED status/control bits */ +#define ED_TAILP_OFFSET (0x04) /* TD Queue Tail Pointer (TailP) */ +#define ED_HEADP_OFFSET (0x08) /* TD Queue Head Pointer (HeadP) */ +#define ED_NEXTED_OFFSET (0x0c) /* Next Endpoint Descriptor (NextED) */ + +/* Endpoint Descriptor Bit Definitions (4.2.2) */ + +#define ED_CONTROL_FA_SHIFT (0) /* Bits 0-6: Function Address */ +#define ED_CONTROL_FA_MASK (0x7f << ED_CONTROL_FA_SHIFT) +#define ED_CONTROL_EN_SHIFT (7) /* Bits 7-10: Endpoint number */ +#define ED_CONTROL_EN_MASK (15 << ED_CONTROL_EN_SHIFT) +#define ED_CONTROL_D_SHIFT (11) /* Bits 11-12: Direction */ +#define ED_CONTROL_D_MASK (3 << ED_CONTROL_D_SHIFT) +# define ED_CONTROL_D_TD1 (0 << ED_CONTROL_D_SHIFT) /* Get direction from TD */ +# define ED_CONTROL_D_OUT (1 << ED_CONTROL_D_SHIFT) /* OUT */ +# define ED_CONTROL_D_IN (2 << ED_CONTROL_D_SHIFT) /* IN */ +# define ED_CONTROL_D_TD2 (3 << ED_CONTROL_D_SHIFT) /* Get direction from TD */ + +#define ED_CONTROL_S (1 << 13) /* Bit 13: Speed (low) */ +#define ED_CONTROL_K (1 << 14) /* Bit 14: Skip */ +#define ED_CONTROL_F (1 << 15) /* Bit 15: Format (isochronous) */ +#define ED_CONTROL_MPS_SHIFT (16) /* Bits 16-26: Maximum packet size */ +#define ED_CONTROL_MPS_MASK (0x7ff << ED_CONTROL_MPS_SHIFT) + +#define ED_HEADP_ADDR_SHIFT (0) +#define ED_HEADP_ADDR_MASK 0xfffffff0 +#define ED_HEADP_H (1 << 0) /* Bit 0: Halted */ +#define ED_HEADP_C (1 << 1) /* Bit 1: Toggle carry */ + +/* General Transfer Descriptor Offsets (4.3.1) */ + +#define GTD_STATUS_OFFSET (0x00) /* TD status bits */ +#define GTD_CBP_OFFSET (0x04) /* Current Buffer Pointer (CBP) */ +#define GTD_NEXTTD_OFFSET (0x08) /* Next TD (NextTD) */ +#define GTD_BE_OFFSET (0x0c) /* Buffer End (BE) */ + +/* General Transfer Descriptor Bit Definitions */ + + /* Bits 0-17: Reserved */ + +#define GTD_STATUS_R (1 << 18) /* Bit 18: Buffer rounding */ +#define GTD_STATUS_DP_SHIFT (19) /* Bits 19-20: Direction/PID */ +#define GTD_STATUS_DP_MASK (3 << GTD_STATUS_DP_SHIFT) +# define GTD_STATUS_DP_SETUP (0 << GTD_STATUS_DP_SHIFT) /* To endpoint */ +# define GTD_STATUS_DP_OUT (1 << GTD_STATUS_DP_SHIFT) /* To endpoint */ +# define GTD_STATUS_DP_IN (2 << GTD_STATUS_DP_SHIFT) /* From endpoint */ + +#define GTD_STATUS_DI_SHIFT (21) /* Bits 21-23: Delay input */ +#define GTD_STATUS_DI_MASK (7 << GTD_STATUS_DI_SHIFT) +#define GTD_STATUS_T_SHIFT (24) /* Bits 24-25: Data Toggle */ +#define GTD_STATUS_T_MASK (3 << GTD_STATUS_T_SHIFT) +# define GTD_STATUS_T_TOGGLE (0 << GTD_STATUS_T_SHIFT) +# define GTD_STATUS_T_DATA0 (2 << GTD_STATUS_T_SHIFT) +# define GTD_STATUS_T_DATA1 (3 << GTD_STATUS_T_SHIFT) +#define GTD_STATUS_EC_SHIFT (26) /* Bits 26-27: Error count */ +#define GTD_STATUS_EC_MASK (3 << GTD_STATUS_EC_SHIFT) +#define GTD_STATUS_CC_SHIFT (28) /* Bits 28-31: Condition code */ +#define GTD_STATUS_CC_MASK (15 << GTD_STATUS_CC_SHIFT) + +/* Isochronous Transfer Descriptor Offsets (4.3.2) */ + +#define ITD_STATUS_OFFSET (0x00) /* TD status bits */ +#define ITD_BP0_OFFSET (0x04) /* Buffer page 0 (BP0) */ +#define ITD_NEXTTD_OFFSET (0x08) /* Next TD (NextTD) */ +#define ITD_BE_OFFSET (0x0c) /* Buffer End (BE) */ + +#define ITD_NPSW (8) +#define ITD_PSW0_OFFSET (0x10) /* Offset0/PSW0 */ +#define ITD_PSW1_OFFSET (0x12) /* Offset1/PSW1 */ +#define ITD_PSW2_OFFSET (0x14) /* Offset2/PSW2 */ +#define ITD_PSW3_OFFSET (0x16) /* Offset3/PSW3 */ +#define ITD_PSW4_OFFSET (0x18) /* Offset4/PSW4 */ +#define ITD_PSW5_OFFSET (0x1a) /* Offset5/PSW5 */ +#define ITD_PSW6_OFFSET (0x1c) /* Offset6/PSW6 */ +#define ITD_PSW7_OFFSET (0x1e) /* Offset7/PSW7 */ + +/* Condition codes (Table 4-7) */ + +#define TD_CC_NOERROR 0x00 +#define TD_CC_CRC 0x01 +#define TD_CC_BITSTUFFING 0x02 +#define TD_CC_DATATOGGLEMISMATCH 0x03 +#define TD_CC_STALL 0x04 +#define TD_CC_DEVNOTRESPONDING 0x05 +#define TD_CC_PIDCHECKFAILURE 0x06 +#define TD_CC_UNEXPECTEDPID 0x07 +#define TD_CC_DATAOVERRUN 0x08 +#define TD_CC_DATAUNDERRUN 0x09 +#define TD_CC_BUFFEROVERRUN 0x0c +#define TD_CC_BUFFERUNDERRUN 0x0d +#define TD_CC_NOTACCESSED 0x0f + +#define TD_CC_USER 0x10 /* For use by OHCI drivers */ + +/* Host Controller Communications Area Format (4.4.1) ***********************/ + +/* HccaInterruptTable: 32x32-bit pointers to interrupt EDs */ + +#define HCCA_INTTBL_OFFSET (0x00) +#define HCCA_INTTBL_WSIZE (32) +#define HCCA_INTTBL_BSIZE (HCCA_INTTBL_WSIZE * 4) + +/* HccaFrameNumber: Current frame number */ + +#define HCCA_FMNO_OFFSET (0x80) +#define HCCA_FMNO_BSIZE (2) + +/* HccaPad1: Zero when frame no. updated */ + +#define HCCA_PAD1_OFFSET (0x82) +#define HCCA_PAD1_BSIZE (2) + +/* HccaDoneHead: When the HC reaches the end of a frame and its deferred + * interrupt register is 0, it writes the current value of its HcDoneHead to + * this location and generates an interrupt. + * + * The LSB of HCCADoneHead may be set to 1 to indicate that an unmasked + * HcInterruptStatus was set when HccaDoneHead was written. + */ + +#define HCCA_DONEHEAD_OFFSET (0x84) +#define HCCA_DONEHEAD_BSIZE (4) + +#define HCCA_DONEHEAD_MASK 0xfffffffe +#define HCCA_DONEHEAD_INTSTA (1 << 0) + +/* 0x88: 116 bytes reserved */ + +#define HCCA_RESERVED_OFFSET (0x88) +#define HCCA_RESERVED_BSIZE (116) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct ohci_hcor +{ + volatile uint32_t hcrevision; /* 0x00 */ + volatile uint32_t hccontrol; /* 0x04 */ + volatile uint32_t hccmdsts; /* 0x08 */ + volatile uint32_t hcintsts; /* 0x0c */ + volatile uint32_t hcinten; /* 0x10 */ + volatile uint32_t hcintdis; /* 0x14 */ + volatile uint32_t hchcca; /* 0x18 */ + volatile uint32_t hcperiodcurrented; /* 0x1c */ + volatile uint32_t hccontrolheaded; /* 0x20 */ + volatile uint32_t hccontrolcurrented; /* 0x24 */ + volatile uint32_t hcbulkheaded; /* 0x28 */ + volatile uint32_t hcbulkcurrented; /* 0x2c */ + volatile uint32_t hcdonehead; /* 0x30 */ + volatile uint32_t hcfminterval; /* 0x34 */ + volatile uint32_t hcfmremaining; /* 0x38 */ + volatile uint32_t hcfmnumber; /* 0x3c */ + volatile uint32_t hcperiodicstart; /* 0x40 */ + volatile uint32_t hclsthreshold; /* 0x44 */ + volatile uint32_t hcrhdescriptora; /* 0x48 */ + volatile uint32_t hcrhdescriptorb; /* 0x4c */ + volatile uint32_t hcrhsts; /* 0x50 */ + volatile uint32_t hcrhportsts[15]; /* 0x54 */ +}; + +/* Endpoint Descriptor Offsets (4.2.1) */ + +struct ohci_ed_s +{ + volatile uint32_t ctrl; /* ED status/control bits */ + volatile uint32_t tailp; /* TD Queue Tail Pointer (TailP) */ + volatile uint32_t headp; /* TD Queue Head Pointer (HeadP) */ + volatile uint32_t nexted; /* Next Endpoint Descriptor (NextED) */ +}; + +/* General Transfer Descriptor (4.3.1) */ + +struct ohci_gtd_s +{ + volatile uint32_t ctrl; /* TD status/control bits */ + volatile uint32_t cbp; /* Current Buffer Pointer (CBP) */ + volatile uint32_t nexttd; /* Next TD (NextTD) */ + volatile uint32_t be; /* Buffer End (BE) */ +}; + +/* Isochronous Transfer Descriptor Offsets (4.3.2) */ + +struct ohci_itd_s +{ + volatile uint32_t ctrl; /* TD status/control bits */ + volatile uint32_t bp0; /* Buffer page 0 (BP0 */ + volatile uint32_t nexttd; /* Next TD (NextTD) */ + volatile uint32_t be; /* Buffer End (BE) */ + volatile uint16_t psw[ITD_NPSW]; /* Offset/PSW */ +}; + +/* Host Controller Communications Area Format (4.4.1) */ + +struct ohci_hcca_s +{ + /* HccaInterruptTable: 32x32-bit pointers to interrupt EDs */ + + volatile uint32_t inttbl[HCCA_INTTBL_WSIZE]; + + /* HccaFrameNumber: Current frame number and + * HccaPad1: Zero when frame no. updated + */ + + volatile uint16_t fmno; + volatile uint16_t pad1; + + /* HccaDoneHead: When the HC reaches the end of a frame and its deferred + * interrupt register is 0, it writes the current value of its HcDoneHead + * to this location and generates an interrupt. + */ + + volatile uint32_t donehead; + volatile uint8_t reserved[HCCA_RESERVED_BSIZE]; + volatile uint32_t extra; +} __attribute__((aligned(256))); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __INCLUDE_NUTTX_USB_OHCI_H */