217 lines
6 KiB
C
217 lines
6 KiB
C
/******************************************************************************
|
|
* Copyright (c) 2007, 2012, 2013 IBM Corporation
|
|
* All rights reserved.
|
|
* This program and the accompanying materials
|
|
* are made available under the terms of the BSD License
|
|
* which accompanies this distribution, and is available at
|
|
* http://www.opensource.org/licenses/bsd-license.php
|
|
*
|
|
* Contributors:
|
|
* IBM Corporation - initial implementation
|
|
*****************************************************************************/
|
|
/*
|
|
* Definitions for OHCI Controller
|
|
*
|
|
* USB on the PowerStation:
|
|
* ohci0 - port 0 -> not connected
|
|
* ohci0 - port 1 - 2 -> Internal connector (J60_USBINT)
|
|
* ohci1 - port 0 -> not connected
|
|
* ohci1 - port 1 - 2 -> External connector (J10_USBEXT)
|
|
*/
|
|
|
|
#ifndef USB_OHCI_H
|
|
#define USB_OHCI_H
|
|
|
|
#include <stdint.h>
|
|
|
|
struct ohci_regs {
|
|
uint32_t rev;
|
|
uint32_t control;
|
|
uint32_t cmd_status;
|
|
uint32_t intr_status;
|
|
uint32_t intr_enable;
|
|
uint32_t intr_disable;
|
|
uint32_t hcca;
|
|
uint32_t period_curr_ed;
|
|
uint32_t cntl_head_ed;
|
|
uint32_t cntl_curr_ed;
|
|
uint32_t bulk_head_ed;
|
|
uint32_t bulk_curr_ed;
|
|
uint32_t done_head;
|
|
uint32_t fm_interval;
|
|
uint32_t fm_remaining;
|
|
uint32_t fm_num;
|
|
uint32_t period_start;
|
|
uint32_t ls_threshold;
|
|
uint32_t rh_desc_a;
|
|
uint32_t rh_desc_b;
|
|
uint32_t rh_status;
|
|
uint32_t rh_ps[5];
|
|
} __attribute__((packed, aligned(4)));
|
|
|
|
#define EDA_FADDR(x) ((x & 0x7F))
|
|
#define EDA_EP(x) ((x & 0x0F) << 7)
|
|
#define EDA_DIR_OUT (1 << 11)
|
|
#define EDA_DIR_IN (1 << 12)
|
|
#define EDA_LOW_SPEED (1 << 13)
|
|
#define EDA_SKIP (1 << 14)
|
|
#define EDA_SKIP_LE (0x400000) /* avoiding conversions */
|
|
#define EDA_FORMAT_ISO (1 << 15)
|
|
#define EDA_MPS(x) ((x & 0x7FF) << 16)
|
|
|
|
#define EDA_HEADP_MASK (0xFFFFFFFC)
|
|
#define EDA_HEADP_MASK_LE (cpu_to_le32(EDA_HEADP_MASK))
|
|
#define EDA_HEADP_HALTED (0x1)
|
|
#define EDA_HEADP_CARRY (0x2)
|
|
|
|
struct ohci_ed {
|
|
uint32_t attr;
|
|
uint32_t tailp;
|
|
uint32_t headp;
|
|
uint32_t next_ed;
|
|
} __attribute__((packed));
|
|
|
|
#define TDA_DONE (1 << 17)
|
|
#define TDA_ROUNDING (1 << 18)
|
|
#define TDA_DP_SETUP (0 << 19)
|
|
#define TDA_DP_OUT (1 << 19)
|
|
#define TDA_DP_IN (1 << 20)
|
|
#define TDA_DI_NO (0x7 << 21)
|
|
#define TDA_TOGGLE_DATA0 (0x02000000)
|
|
#define TDA_TOGGLE_DATA1 (0x03000000)
|
|
#define TDA_CC (0xF << 28)
|
|
|
|
#define TDA_ERROR(x) ((x) * -1)
|
|
|
|
/* Table 4-7: Completion Codes */
|
|
const char *tda_cc_error[] = {
|
|
#define USB_NOERROR TDA_ERROR(0)
|
|
"NOERROR",
|
|
"CRC",
|
|
"BITSTUFFING",
|
|
"DATATOGGLEMISMATCH",
|
|
#define USB_STALL TDA_ERROR(4)
|
|
"STALL",
|
|
"DEVICENOTRESPONDING",
|
|
"PIDCHECKFAILURE",
|
|
"UNEXPECTEDPID",
|
|
"DATAOVERRUN",
|
|
"DATAUNDERRUN",
|
|
"reserved",
|
|
"reserved",
|
|
"BUFFEROVERRUN",
|
|
"BUFFERUNDERRUN",
|
|
"NOT ACCESSED",
|
|
"NOT ACCESSED",
|
|
};
|
|
|
|
struct ohci_td {
|
|
uint32_t attr;
|
|
uint32_t cbp;
|
|
uint32_t next_td;
|
|
uint32_t be;
|
|
} __attribute__((packed));
|
|
|
|
#define HCCA_SIZE 256
|
|
#define HCCA_ALIGN (HCCA_SIZE - 1)
|
|
#define HCCA_INTR_NUM 32
|
|
struct ohci_hcca {
|
|
uint32_t intr_table[HCCA_INTR_NUM];
|
|
uint16_t frame_num;
|
|
uint16_t pad1;
|
|
uint32_t done_head;
|
|
uint32_t reserved[120];
|
|
} __attribute__((packed));
|
|
|
|
struct ohci_pipe {
|
|
struct ohci_ed ed; /* has to be aligned at 16 byte address*/
|
|
struct usb_pipe pipe;
|
|
struct ohci_td *td;
|
|
void *buf;
|
|
long ed_phys;
|
|
long td_phys;
|
|
long buf_phys;
|
|
uint32_t buflen;
|
|
uint32_t count;
|
|
uint8_t pad[0];
|
|
}__attribute__((packed));
|
|
|
|
#define OHCI_PIPE_POOL_SIZE 4096
|
|
#define OHCI_MAX_TDS 256 /* supports 16k buffers, i.e. 64 * 256 */
|
|
#define OHCI_MAX_BULK_SIZE 4096
|
|
|
|
struct ohci_hcd {
|
|
struct ohci_hcca *hcca;
|
|
struct ohci_regs *regs;
|
|
struct usb_hcd_dev *hcidev;
|
|
struct usb_pipe *freelist;
|
|
struct usb_pipe *end;
|
|
struct usb_dev rhdev;
|
|
long hcca_phys;
|
|
void *pool;
|
|
long pool_phys;
|
|
};
|
|
|
|
#define OHCI_CTRL_CBSR (3 << 0)
|
|
#define OHCI_CTRL_PLE (1 << 2)
|
|
#define OHCI_CTRL_CLE (1 << 4)
|
|
#define OHCI_CTRL_BLE (1 << 5)
|
|
#define OHCI_CTRL_HCFS (3 << 6)
|
|
#define OHCI_USB_RESET (0 << 6)
|
|
#define OHCI_USB_OPER (2 << 6)
|
|
#define OHCI_USB_SUSPEND (3 << 6)
|
|
#define OHCI_CTRL_RWC (1 << 9)
|
|
|
|
/* OHCI Command Status */
|
|
#define OHCI_CMD_STATUS_HCR (1 << 0)
|
|
#define OHCI_CMD_STATUS_CLF (1 << 1)
|
|
#define OHCI_CMD_STATUS_BLF (1 << 2)
|
|
|
|
/* OHCI Interrupt status */
|
|
#define OHCI_INTR_STATUS_WD (1 << 1)
|
|
|
|
/* Root Hub Descriptor A bits */
|
|
#define RHDA_NDP (0xFF)
|
|
#define RHDA_PSM_INDIVIDUAL (1 << 8)
|
|
#define RHDA_NPS_ENABLE (1 << 9)
|
|
#define RHDA_DT (1 << 10)
|
|
#define RHDA_OCPM_PERPORT (1 << 11)
|
|
#define RHDA_NOCP_ENABLE (1 << 12)
|
|
|
|
/* Root Hub Descriptor B bits */
|
|
#define RHDB_PPCM_PORT_POWER (0xFFFE)
|
|
#define RHDB_PPCM_GLOBAL_POWER (0x0000)
|
|
|
|
#define RH_STATUS_LPSC (1 << 16)
|
|
#define RH_STATUS_OCIC (1 << 17)
|
|
#define RH_STATUS_CREW (1 << 31)
|
|
|
|
#define RH_PS_CCS (1 << 0)
|
|
#define RH_PS_PES (1 << 1)
|
|
#define RH_PS_PSS (1 << 2)
|
|
#define RH_PS_POCI (1 << 3)
|
|
#define RH_PS_PRS (1 << 4)
|
|
#define RH_PS_PPS (1 << 8)
|
|
#define RH_PS_LSDA (1 << 9)
|
|
|
|
#define RH_PS_CSC (1 << 16)
|
|
#define RH_PS_PESC (1 << 17)
|
|
#define RH_PS_PSSC (1 << 18)
|
|
#define RH_PS_OCIC (1 << 19)
|
|
#define RH_PS_PRSC (1 << 20)
|
|
|
|
/*********************************************************************/
|
|
/* Values for USB Frame Timing */
|
|
/* One USB frame (1ms) consists of 12000 bit-times as clock is 12MHz */
|
|
/* controller can be adjusted for performance optimization */
|
|
/* We use standard values (OHCI spec 6.3.1, 5.1.1.4, 5.4, 7.3.4) */
|
|
/*********************************************************************/
|
|
#define FRAME_INTERVAL (((((11999 - 210) * 6) / 7) << 16) | 11999)
|
|
#define PERIODIC_START ((11999 * 9) / 10)
|
|
|
|
|
|
static inline struct ohci_ed *ohci_pipe_get_ed(struct usb_pipe *pipe);
|
|
static inline long ohci_pipe_get_ed_phys(struct usb_pipe *pipe);
|
|
static int ohci_alloc_pipe_pool(struct ohci_hcd *ohcd);
|
|
|
|
#endif /* USB_OHCI_H */
|