12731b9a8SJean-Christophe PLAGNIOL-VILLARD /* 22731b9a8SJean-Christophe PLAGNIOL-VILLARD * URB OHCI HCD (Host Controller Driver) for USB. 32731b9a8SJean-Christophe PLAGNIOL-VILLARD * 42731b9a8SJean-Christophe PLAGNIOL-VILLARD * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> 52731b9a8SJean-Christophe PLAGNIOL-VILLARD * (C) Copyright 2000-2001 David Brownell <dbrownell@users.sourceforge.net> 62731b9a8SJean-Christophe PLAGNIOL-VILLARD * 72731b9a8SJean-Christophe PLAGNIOL-VILLARD * usb-ohci.h 82731b9a8SJean-Christophe PLAGNIOL-VILLARD */ 92731b9a8SJean-Christophe PLAGNIOL-VILLARD 10a5496a18SBecky Bruce /* 11a5496a18SBecky Bruce * e.g. PCI controllers need this 12a5496a18SBecky Bruce */ 1357faca19SAndre Przywara 1457faca19SAndre Przywara #include <asm/io.h> 1557faca19SAndre Przywara 16a5496a18SBecky Bruce #ifdef CONFIG_SYS_OHCI_SWAP_REG_ACCESS 1757faca19SAndre Przywara # define ohci_readl(a) __swap_32(readl(a)) 1857faca19SAndre Przywara # define ohci_writel(v, a) writel(__swap_32(v), a) 19a5496a18SBecky Bruce #else 2057faca19SAndre Przywara # define ohci_readl(a) readl(a) 2157faca19SAndre Przywara # define ohci_writel(v, a) writel(v, a) 22a5496a18SBecky Bruce #endif /* CONFIG_SYS_OHCI_SWAP_REG_ACCESS */ 23a5496a18SBecky Bruce 24e0266f49SWu, Josh #if ARCH_DMA_MINALIGN > 16 258d005ef8SHans de Goede #define ED_ALIGNMENT ARCH_DMA_MINALIGN 268d005ef8SHans de Goede #else 278d005ef8SHans de Goede #define ED_ALIGNMENT 16 288d005ef8SHans de Goede #endif 298d005ef8SHans de Goede 30*fd09c205SSven Schwermer #if CONFIG_IS_ENABLED(DM_USB) && ARCH_DMA_MINALIGN > 32 318d005ef8SHans de Goede #define TD_ALIGNMENT ARCH_DMA_MINALIGN 328d005ef8SHans de Goede #else 338d005ef8SHans de Goede #define TD_ALIGNMENT 32 348d005ef8SHans de Goede #endif 358d005ef8SHans de Goede 362731b9a8SJean-Christophe PLAGNIOL-VILLARD /* functions for doing board or CPU specific setup/cleanup */ 3716297cfbSMateusz Zalega int usb_board_stop(void); 382731b9a8SJean-Christophe PLAGNIOL-VILLARD 3916297cfbSMateusz Zalega int usb_cpu_init(void); 4016297cfbSMateusz Zalega int usb_cpu_stop(void); 4116297cfbSMateusz Zalega int usb_cpu_init_fail(void); 422731b9a8SJean-Christophe PLAGNIOL-VILLARD 432731b9a8SJean-Christophe PLAGNIOL-VILLARD /* ED States */ 442731b9a8SJean-Christophe PLAGNIOL-VILLARD #define ED_NEW 0x00 452731b9a8SJean-Christophe PLAGNIOL-VILLARD #define ED_UNLINK 0x01 462731b9a8SJean-Christophe PLAGNIOL-VILLARD #define ED_OPER 0x02 472731b9a8SJean-Christophe PLAGNIOL-VILLARD #define ED_DEL 0x04 482731b9a8SJean-Christophe PLAGNIOL-VILLARD #define ED_URB_DEL 0x08 492731b9a8SJean-Christophe PLAGNIOL-VILLARD 502731b9a8SJean-Christophe PLAGNIOL-VILLARD /* usb_ohci_ed */ 512731b9a8SJean-Christophe PLAGNIOL-VILLARD struct ed { 522731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 hwINFO; 532731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 hwTailP; 542731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 hwHeadP; 552731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 hwNextED; 562731b9a8SJean-Christophe PLAGNIOL-VILLARD 572731b9a8SJean-Christophe PLAGNIOL-VILLARD struct ed *ed_prev; 582731b9a8SJean-Christophe PLAGNIOL-VILLARD __u8 int_period; 592731b9a8SJean-Christophe PLAGNIOL-VILLARD __u8 int_branch; 602731b9a8SJean-Christophe PLAGNIOL-VILLARD __u8 int_load; 612731b9a8SJean-Christophe PLAGNIOL-VILLARD __u8 int_interval; 622731b9a8SJean-Christophe PLAGNIOL-VILLARD __u8 state; 632731b9a8SJean-Christophe PLAGNIOL-VILLARD __u8 type; 642731b9a8SJean-Christophe PLAGNIOL-VILLARD __u16 last_iso; 652731b9a8SJean-Christophe PLAGNIOL-VILLARD struct ed *ed_rm_list; 662731b9a8SJean-Christophe PLAGNIOL-VILLARD 672731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_device *usb_dev; 682731b9a8SJean-Christophe PLAGNIOL-VILLARD void *purb; 692731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 unused[2]; 708d005ef8SHans de Goede } __attribute__((aligned(ED_ALIGNMENT))); 712731b9a8SJean-Christophe PLAGNIOL-VILLARD typedef struct ed ed_t; 722731b9a8SJean-Christophe PLAGNIOL-VILLARD 732731b9a8SJean-Christophe PLAGNIOL-VILLARD 742731b9a8SJean-Christophe PLAGNIOL-VILLARD /* TD info field */ 752731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_CC 0xf0000000 762731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_CC_GET(td_p) ((td_p >>28) & 0x0f) 772731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28) 782731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_EC 0x0C000000 792731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_T 0x03000000 802731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_T_DATA0 0x02000000 812731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_T_DATA1 0x03000000 822731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_T_TOGGLE 0x00000000 832731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_R 0x00040000 842731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_DI 0x00E00000 852731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_DI_SET(X) (((X) & 0x07)<< 21) 862731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_DP 0x00180000 872731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_DP_SETUP 0x00000000 882731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_DP_IN 0x00100000 892731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_DP_OUT 0x00080000 902731b9a8SJean-Christophe PLAGNIOL-VILLARD 912731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_ISO 0x00010000 922731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_DEL 0x00020000 932731b9a8SJean-Christophe PLAGNIOL-VILLARD 942731b9a8SJean-Christophe PLAGNIOL-VILLARD /* CC Codes */ 952731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_CC_NOERROR 0x00 962731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_CC_CRC 0x01 972731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_CC_BITSTUFFING 0x02 982731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_CC_DATATOGGLEM 0x03 992731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_CC_STALL 0x04 1002731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_DEVNOTRESP 0x05 1012731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_PIDCHECKFAIL 0x06 1022731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_UNEXPECTEDPID 0x07 1032731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_DATAOVERRUN 0x08 1042731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_DATAUNDERRUN 0x09 1052731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_BUFFEROVERRUN 0x0C 1062731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_BUFFERUNDERRUN 0x0D 1072731b9a8SJean-Christophe PLAGNIOL-VILLARD #define TD_NOTACCESSED 0x0F 1082731b9a8SJean-Christophe PLAGNIOL-VILLARD 1092731b9a8SJean-Christophe PLAGNIOL-VILLARD 1102731b9a8SJean-Christophe PLAGNIOL-VILLARD #define MAXPSW 1 1112731b9a8SJean-Christophe PLAGNIOL-VILLARD 1122731b9a8SJean-Christophe PLAGNIOL-VILLARD struct td { 1132731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 hwINFO; 1142731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 hwCBP; /* Current Buffer Pointer */ 1152731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 hwNextTD; /* Next TD Pointer */ 1162731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 hwBE; /* Memory Buffer End Pointer */ 1172731b9a8SJean-Christophe PLAGNIOL-VILLARD 1182731b9a8SJean-Christophe PLAGNIOL-VILLARD __u16 hwPSW[MAXPSW]; 1192731b9a8SJean-Christophe PLAGNIOL-VILLARD __u8 unused; 1202731b9a8SJean-Christophe PLAGNIOL-VILLARD __u8 index; 1212731b9a8SJean-Christophe PLAGNIOL-VILLARD struct ed *ed; 1222731b9a8SJean-Christophe PLAGNIOL-VILLARD struct td *next_dl_td; 1232731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_device *usb_dev; 1242731b9a8SJean-Christophe PLAGNIOL-VILLARD int transfer_len; 1252731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 data; 1262731b9a8SJean-Christophe PLAGNIOL-VILLARD 1272731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 unused2[2]; 1288d005ef8SHans de Goede } __attribute__((aligned(TD_ALIGNMENT))); 1292731b9a8SJean-Christophe PLAGNIOL-VILLARD typedef struct td td_t; 1302731b9a8SJean-Christophe PLAGNIOL-VILLARD 1312731b9a8SJean-Christophe PLAGNIOL-VILLARD #define OHCI_ED_SKIP (1 << 14) 1322731b9a8SJean-Christophe PLAGNIOL-VILLARD 1332731b9a8SJean-Christophe PLAGNIOL-VILLARD /* 1342731b9a8SJean-Christophe PLAGNIOL-VILLARD * The HCCA (Host Controller Communications Area) is a 256 byte 1352731b9a8SJean-Christophe PLAGNIOL-VILLARD * structure defined in the OHCI spec. that the host controller is 1362731b9a8SJean-Christophe PLAGNIOL-VILLARD * told the base address of. It must be 256-byte aligned. 1372731b9a8SJean-Christophe PLAGNIOL-VILLARD */ 1382731b9a8SJean-Christophe PLAGNIOL-VILLARD 1392731b9a8SJean-Christophe PLAGNIOL-VILLARD #define NUM_INTS 32 /* part of the OHCI standard */ 1402731b9a8SJean-Christophe PLAGNIOL-VILLARD struct ohci_hcca { 1412731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 int_table[NUM_INTS]; /* Interrupt ED table */ 1422731b9a8SJean-Christophe PLAGNIOL-VILLARD __u16 frame_no; /* current frame number */ 1432731b9a8SJean-Christophe PLAGNIOL-VILLARD __u16 pad1; /* set to 0 on each frame_no change */ 1442731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 done_head; /* info returned for an interrupt */ 1452731b9a8SJean-Christophe PLAGNIOL-VILLARD u8 reserved_for_hc[116]; 146f9a109b3SPeter Tyser } __attribute__((aligned(256))); 1472731b9a8SJean-Christophe PLAGNIOL-VILLARD 1482731b9a8SJean-Christophe PLAGNIOL-VILLARD 1492731b9a8SJean-Christophe PLAGNIOL-VILLARD /* 1502731b9a8SJean-Christophe PLAGNIOL-VILLARD * Maximum number of root hub ports. 1512731b9a8SJean-Christophe PLAGNIOL-VILLARD */ 1522731b9a8SJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 1532731b9a8SJean-Christophe PLAGNIOL-VILLARD # error "CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS undefined!" 1542731b9a8SJean-Christophe PLAGNIOL-VILLARD #endif 1552731b9a8SJean-Christophe PLAGNIOL-VILLARD 1562731b9a8SJean-Christophe PLAGNIOL-VILLARD /* 1572731b9a8SJean-Christophe PLAGNIOL-VILLARD * This is the structure of the OHCI controller's memory mapped I/O 158a5496a18SBecky Bruce * region. This is Memory Mapped I/O. You must use the ohci_readl() and 159a5496a18SBecky Bruce * ohci_writel() macros defined in this file to access these!! 1602731b9a8SJean-Christophe PLAGNIOL-VILLARD */ 1612731b9a8SJean-Christophe PLAGNIOL-VILLARD struct ohci_regs { 1622731b9a8SJean-Christophe PLAGNIOL-VILLARD /* control and status registers */ 1632731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 revision; 1642731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 control; 1652731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 cmdstatus; 1662731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 intrstatus; 1672731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 intrenable; 1682731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 intrdisable; 1692731b9a8SJean-Christophe PLAGNIOL-VILLARD /* memory pointers */ 1702731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 hcca; 1712731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 ed_periodcurrent; 1722731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 ed_controlhead; 1732731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 ed_controlcurrent; 1742731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 ed_bulkhead; 1752731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 ed_bulkcurrent; 1762731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 donehead; 1772731b9a8SJean-Christophe PLAGNIOL-VILLARD /* frame counters */ 1782731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 fminterval; 1792731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 fmremaining; 1802731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 fmnumber; 1812731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 periodicstart; 1822731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 lsthresh; 1832731b9a8SJean-Christophe PLAGNIOL-VILLARD /* Root hub ports */ 1842731b9a8SJean-Christophe PLAGNIOL-VILLARD struct ohci_roothub_regs { 1852731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 a; 1862731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 b; 1872731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 status; 1882731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 portstatus[CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS]; 1892731b9a8SJean-Christophe PLAGNIOL-VILLARD } roothub; 190f9a109b3SPeter Tyser } __attribute__((aligned(32))); 1912731b9a8SJean-Christophe PLAGNIOL-VILLARD 1922731b9a8SJean-Christophe PLAGNIOL-VILLARD /* Some EHCI controls */ 1932731b9a8SJean-Christophe PLAGNIOL-VILLARD #define EHCI_USBCMD_OFF 0x20 1942731b9a8SJean-Christophe PLAGNIOL-VILLARD #define EHCI_USBCMD_HCRESET (1 << 1) 1952731b9a8SJean-Christophe PLAGNIOL-VILLARD 1962731b9a8SJean-Christophe PLAGNIOL-VILLARD /* OHCI CONTROL AND STATUS REGISTER MASKS */ 1972731b9a8SJean-Christophe PLAGNIOL-VILLARD 1982731b9a8SJean-Christophe PLAGNIOL-VILLARD /* 1992731b9a8SJean-Christophe PLAGNIOL-VILLARD * HcControl (control) register masks 2002731b9a8SJean-Christophe PLAGNIOL-VILLARD */ 2012731b9a8SJean-Christophe PLAGNIOL-VILLARD #define OHCI_CTRL_CBSR (3 << 0) /* control/bulk service ratio */ 2022731b9a8SJean-Christophe PLAGNIOL-VILLARD #define OHCI_CTRL_PLE (1 << 2) /* periodic list enable */ 2032731b9a8SJean-Christophe PLAGNIOL-VILLARD #define OHCI_CTRL_IE (1 << 3) /* isochronous enable */ 2042731b9a8SJean-Christophe PLAGNIOL-VILLARD #define OHCI_CTRL_CLE (1 << 4) /* control list enable */ 2052731b9a8SJean-Christophe PLAGNIOL-VILLARD #define OHCI_CTRL_BLE (1 << 5) /* bulk list enable */ 2062731b9a8SJean-Christophe PLAGNIOL-VILLARD #define OHCI_CTRL_HCFS (3 << 6) /* host controller functional state */ 2072731b9a8SJean-Christophe PLAGNIOL-VILLARD #define OHCI_CTRL_IR (1 << 8) /* interrupt routing */ 2082731b9a8SJean-Christophe PLAGNIOL-VILLARD #define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */ 2092731b9a8SJean-Christophe PLAGNIOL-VILLARD #define OHCI_CTRL_RWE (1 << 10) /* remote wakeup enable */ 2102731b9a8SJean-Christophe PLAGNIOL-VILLARD 2112731b9a8SJean-Christophe PLAGNIOL-VILLARD /* pre-shifted values for HCFS */ 2122731b9a8SJean-Christophe PLAGNIOL-VILLARD # define OHCI_USB_RESET (0 << 6) 2132731b9a8SJean-Christophe PLAGNIOL-VILLARD # define OHCI_USB_RESUME (1 << 6) 2142731b9a8SJean-Christophe PLAGNIOL-VILLARD # define OHCI_USB_OPER (2 << 6) 2152731b9a8SJean-Christophe PLAGNIOL-VILLARD # define OHCI_USB_SUSPEND (3 << 6) 2162731b9a8SJean-Christophe PLAGNIOL-VILLARD 2172731b9a8SJean-Christophe PLAGNIOL-VILLARD /* 2182731b9a8SJean-Christophe PLAGNIOL-VILLARD * HcCommandStatus (cmdstatus) register masks 2192731b9a8SJean-Christophe PLAGNIOL-VILLARD */ 2202731b9a8SJean-Christophe PLAGNIOL-VILLARD #define OHCI_HCR (1 << 0) /* host controller reset */ 2212731b9a8SJean-Christophe PLAGNIOL-VILLARD #define OHCI_CLF (1 << 1) /* control list filled */ 2222731b9a8SJean-Christophe PLAGNIOL-VILLARD #define OHCI_BLF (1 << 2) /* bulk list filled */ 2232731b9a8SJean-Christophe PLAGNIOL-VILLARD #define OHCI_OCR (1 << 3) /* ownership change request */ 2242731b9a8SJean-Christophe PLAGNIOL-VILLARD #define OHCI_SOC (3 << 16) /* scheduling overrun count */ 2252731b9a8SJean-Christophe PLAGNIOL-VILLARD 2262731b9a8SJean-Christophe PLAGNIOL-VILLARD /* 2272731b9a8SJean-Christophe PLAGNIOL-VILLARD * masks used with interrupt registers: 2282731b9a8SJean-Christophe PLAGNIOL-VILLARD * HcInterruptStatus (intrstatus) 2292731b9a8SJean-Christophe PLAGNIOL-VILLARD * HcInterruptEnable (intrenable) 2302731b9a8SJean-Christophe PLAGNIOL-VILLARD * HcInterruptDisable (intrdisable) 2312731b9a8SJean-Christophe PLAGNIOL-VILLARD */ 2322731b9a8SJean-Christophe PLAGNIOL-VILLARD #define OHCI_INTR_SO (1 << 0) /* scheduling overrun */ 2332731b9a8SJean-Christophe PLAGNIOL-VILLARD #define OHCI_INTR_WDH (1 << 1) /* writeback of done_head */ 2342731b9a8SJean-Christophe PLAGNIOL-VILLARD #define OHCI_INTR_SF (1 << 2) /* start frame */ 2352731b9a8SJean-Christophe PLAGNIOL-VILLARD #define OHCI_INTR_RD (1 << 3) /* resume detect */ 2362731b9a8SJean-Christophe PLAGNIOL-VILLARD #define OHCI_INTR_UE (1 << 4) /* unrecoverable error */ 2372731b9a8SJean-Christophe PLAGNIOL-VILLARD #define OHCI_INTR_FNO (1 << 5) /* frame number overflow */ 2382731b9a8SJean-Christophe PLAGNIOL-VILLARD #define OHCI_INTR_RHSC (1 << 6) /* root hub status change */ 2392731b9a8SJean-Christophe PLAGNIOL-VILLARD #define OHCI_INTR_OC (1 << 30) /* ownership change */ 2402731b9a8SJean-Christophe PLAGNIOL-VILLARD #define OHCI_INTR_MIE (1 << 31) /* master interrupt enable */ 2412731b9a8SJean-Christophe PLAGNIOL-VILLARD 2422731b9a8SJean-Christophe PLAGNIOL-VILLARD 2432731b9a8SJean-Christophe PLAGNIOL-VILLARD /* Virtual Root HUB */ 2442731b9a8SJean-Christophe PLAGNIOL-VILLARD struct virt_root_hub { 2452731b9a8SJean-Christophe PLAGNIOL-VILLARD int devnum; /* Address of Root Hub endpoint */ 2462731b9a8SJean-Christophe PLAGNIOL-VILLARD void *dev; /* was urb */ 2472731b9a8SJean-Christophe PLAGNIOL-VILLARD void *int_addr; 2482731b9a8SJean-Christophe PLAGNIOL-VILLARD int send; 2492731b9a8SJean-Christophe PLAGNIOL-VILLARD int interval; 2502731b9a8SJean-Christophe PLAGNIOL-VILLARD }; 2512731b9a8SJean-Christophe PLAGNIOL-VILLARD 2522731b9a8SJean-Christophe PLAGNIOL-VILLARD /* USB HUB CONSTANTS (not OHCI-specific; see hub.h) */ 2532731b9a8SJean-Christophe PLAGNIOL-VILLARD 2542731b9a8SJean-Christophe PLAGNIOL-VILLARD /* destination of request */ 2552731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_INTERFACE 0x01 2562731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_ENDPOINT 0x02 2572731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_OTHER 0x03 2582731b9a8SJean-Christophe PLAGNIOL-VILLARD 2592731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_CLASS 0x20 2602731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_VENDOR 0x40 2612731b9a8SJean-Christophe PLAGNIOL-VILLARD 2622731b9a8SJean-Christophe PLAGNIOL-VILLARD /* Requests: bRequest << 8 | bmRequestType */ 2632731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_GET_STATUS 0x0080 2642731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_CLEAR_FEATURE 0x0100 2652731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_SET_FEATURE 0x0300 2662731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_SET_ADDRESS 0x0500 2672731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_GET_DESCRIPTOR 0x0680 2682731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_SET_DESCRIPTOR 0x0700 2692731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_GET_CONFIGURATION 0x0880 2702731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_SET_CONFIGURATION 0x0900 2712731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_GET_STATE 0x0280 2722731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_GET_INTERFACE 0x0A80 2732731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_SET_INTERFACE 0x0B00 2742731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_SYNC_FRAME 0x0C80 2752731b9a8SJean-Christophe PLAGNIOL-VILLARD /* Our Vendor Specific Request */ 2762731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_SET_EP 0x2000 2772731b9a8SJean-Christophe PLAGNIOL-VILLARD 2782731b9a8SJean-Christophe PLAGNIOL-VILLARD 2792731b9a8SJean-Christophe PLAGNIOL-VILLARD /* Hub port features */ 2802731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_PORT_CONNECTION 0x00 2812731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_PORT_ENABLE 0x01 2822731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_PORT_SUSPEND 0x02 2832731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_PORT_OVER_CURRENT 0x03 2842731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_PORT_RESET 0x04 2852731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_PORT_POWER 0x08 2862731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_PORT_LOW_SPEED 0x09 2872731b9a8SJean-Christophe PLAGNIOL-VILLARD 2882731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_C_PORT_CONNECTION 0x10 2892731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_C_PORT_ENABLE 0x11 2902731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_C_PORT_SUSPEND 0x12 2912731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_C_PORT_OVER_CURRENT 0x13 2922731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_C_PORT_RESET 0x14 2932731b9a8SJean-Christophe PLAGNIOL-VILLARD 2942731b9a8SJean-Christophe PLAGNIOL-VILLARD /* Hub features */ 2952731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_C_HUB_LOCAL_POWER 0x00 2962731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_C_HUB_OVER_CURRENT 0x01 2972731b9a8SJean-Christophe PLAGNIOL-VILLARD 2982731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_DEVICE_REMOTE_WAKEUP 0x00 2992731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_ENDPOINT_STALL 0x01 3002731b9a8SJean-Christophe PLAGNIOL-VILLARD 3012731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_ACK 0x01 3022731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_REQ_ERR -1 3032731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_NACK 0x00 3042731b9a8SJean-Christophe PLAGNIOL-VILLARD 3052731b9a8SJean-Christophe PLAGNIOL-VILLARD 3062731b9a8SJean-Christophe PLAGNIOL-VILLARD /* OHCI ROOT HUB REGISTER MASKS */ 3072731b9a8SJean-Christophe PLAGNIOL-VILLARD 3082731b9a8SJean-Christophe PLAGNIOL-VILLARD /* roothub.portstatus [i] bits */ 3092731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_PS_CCS 0x00000001 /* current connect status */ 3102731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_PS_PES 0x00000002 /* port enable status*/ 3112731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_PS_PSS 0x00000004 /* port suspend status */ 3122731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_PS_POCI 0x00000008 /* port over current indicator */ 3132731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_PS_PRS 0x00000010 /* port reset status */ 3142731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_PS_PPS 0x00000100 /* port power status */ 3152731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_PS_LSDA 0x00000200 /* low speed device attached */ 3162731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_PS_CSC 0x00010000 /* connect status change */ 3172731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_PS_PESC 0x00020000 /* port enable status change */ 3182731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_PS_PSSC 0x00040000 /* port suspend status change */ 3192731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_PS_OCIC 0x00080000 /* over current indicator change */ 3202731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_PS_PRSC 0x00100000 /* port reset status change */ 3212731b9a8SJean-Christophe PLAGNIOL-VILLARD 3222731b9a8SJean-Christophe PLAGNIOL-VILLARD /* roothub.status bits */ 3232731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_HS_LPS 0x00000001 /* local power status */ 3242731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_HS_OCI 0x00000002 /* over current indicator */ 3252731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_HS_DRWE 0x00008000 /* device remote wakeup enable */ 3262731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_HS_LPSC 0x00010000 /* local power status change */ 3272731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_HS_OCIC 0x00020000 /* over current indicator change */ 3282731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_HS_CRWE 0x80000000 /* clear remote wakeup enable */ 3292731b9a8SJean-Christophe PLAGNIOL-VILLARD 3302731b9a8SJean-Christophe PLAGNIOL-VILLARD /* roothub.b masks */ 3312731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_B_DR 0x0000ffff /* device removable flags */ 3322731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_B_PPCM 0xffff0000 /* port power control mask */ 3332731b9a8SJean-Christophe PLAGNIOL-VILLARD 3342731b9a8SJean-Christophe PLAGNIOL-VILLARD /* roothub.a masks */ 3352731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_A_NDP (0xff << 0) /* number of downstream ports */ 3362731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_A_PSM (1 << 8) /* power switching mode */ 3372731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_A_NPS (1 << 9) /* no power switching */ 3382731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_A_DT (1 << 10) /* device type (mbz) */ 3392731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_A_OCPM (1 << 11) /* over current protection mode */ 3402731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_A_NOCP (1 << 12) /* no over current protection */ 3412731b9a8SJean-Christophe PLAGNIOL-VILLARD #define RH_A_POTPGT (0xff << 24) /* power on to power good time */ 3422731b9a8SJean-Christophe PLAGNIOL-VILLARD 3432731b9a8SJean-Christophe PLAGNIOL-VILLARD /* urb */ 3442731b9a8SJean-Christophe PLAGNIOL-VILLARD #define N_URB_TD 48 3452731b9a8SJean-Christophe PLAGNIOL-VILLARD typedef struct 3462731b9a8SJean-Christophe PLAGNIOL-VILLARD { 3472731b9a8SJean-Christophe PLAGNIOL-VILLARD ed_t *ed; 3482731b9a8SJean-Christophe PLAGNIOL-VILLARD __u16 length; /* number of tds associated with this request */ 3492731b9a8SJean-Christophe PLAGNIOL-VILLARD __u16 td_cnt; /* number of tds already serviced */ 3502731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_device *dev; 3512731b9a8SJean-Christophe PLAGNIOL-VILLARD int state; 3522731b9a8SJean-Christophe PLAGNIOL-VILLARD unsigned long pipe; 3532731b9a8SJean-Christophe PLAGNIOL-VILLARD void *transfer_buffer; 3542731b9a8SJean-Christophe PLAGNIOL-VILLARD int transfer_buffer_length; 3552731b9a8SJean-Christophe PLAGNIOL-VILLARD int interval; 3562731b9a8SJean-Christophe PLAGNIOL-VILLARD int actual_length; 3572731b9a8SJean-Christophe PLAGNIOL-VILLARD int finished; 3582731b9a8SJean-Christophe PLAGNIOL-VILLARD td_t *td[N_URB_TD]; /* list pointer to all corresponding TDs associated with this request */ 3592731b9a8SJean-Christophe PLAGNIOL-VILLARD } urb_priv_t; 3602731b9a8SJean-Christophe PLAGNIOL-VILLARD #define URB_DEL 1 3612731b9a8SJean-Christophe PLAGNIOL-VILLARD 36211080bf6SZeng Tao #define NUM_EDS 32 /* num of preallocated endpoint descriptors */ 36319d95d57SHans de Goede 3643c5497d8SHans de Goede #define NUM_TD 64 /* we need more TDs than EDs */ 3653c5497d8SHans de Goede 36644dbc330SHans de Goede #define NUM_INT_DEVS 8 /* num of ohci_dev structs for int endpoints */ 36744dbc330SHans de Goede 36819d95d57SHans de Goede typedef struct ohci_device { 3698d005ef8SHans de Goede ed_t ed[NUM_EDS] __aligned(ED_ALIGNMENT); 3708d005ef8SHans de Goede td_t tds[NUM_TD] __aligned(TD_ALIGNMENT); 37119d95d57SHans de Goede int ed_cnt; 37244dbc330SHans de Goede int devnum; 37319d95d57SHans de Goede } ohci_dev_t; 37419d95d57SHans de Goede 3752731b9a8SJean-Christophe PLAGNIOL-VILLARD /* 3762731b9a8SJean-Christophe PLAGNIOL-VILLARD * This is the full ohci controller description 3772731b9a8SJean-Christophe PLAGNIOL-VILLARD * 3782731b9a8SJean-Christophe PLAGNIOL-VILLARD * Note how the "proper" USB information is just 3792731b9a8SJean-Christophe PLAGNIOL-VILLARD * a subset of what the full implementation needs. (Linus) 3802731b9a8SJean-Christophe PLAGNIOL-VILLARD */ 3812731b9a8SJean-Christophe PLAGNIOL-VILLARD 3822731b9a8SJean-Christophe PLAGNIOL-VILLARD 3832731b9a8SJean-Christophe PLAGNIOL-VILLARD typedef struct ohci { 38419d95d57SHans de Goede /* this allocates EDs for all possible endpoints */ 3858d005ef8SHans de Goede struct ohci_device ohci_dev __aligned(TD_ALIGNMENT); 38644dbc330SHans de Goede struct ohci_device int_dev[NUM_INT_DEVS] __aligned(TD_ALIGNMENT); 3872731b9a8SJean-Christophe PLAGNIOL-VILLARD struct ohci_hcca *hcca; /* hcca */ 3882731b9a8SJean-Christophe PLAGNIOL-VILLARD /*dma_addr_t hcca_dma;*/ 3892731b9a8SJean-Christophe PLAGNIOL-VILLARD 3902731b9a8SJean-Christophe PLAGNIOL-VILLARD int irq; 3912731b9a8SJean-Christophe PLAGNIOL-VILLARD int disabled; /* e.g. got a UE, we're hung */ 3922731b9a8SJean-Christophe PLAGNIOL-VILLARD int sleeping; 3932731b9a8SJean-Christophe PLAGNIOL-VILLARD unsigned long flags; /* for HC bugs */ 3942731b9a8SJean-Christophe PLAGNIOL-VILLARD 3952731b9a8SJean-Christophe PLAGNIOL-VILLARD struct ohci_regs *regs; /* OHCI controller's memory */ 3962731b9a8SJean-Christophe PLAGNIOL-VILLARD 3972731b9a8SJean-Christophe PLAGNIOL-VILLARD int ohci_int_load[32]; /* load of the 32 Interrupt Chains (for load balancing)*/ 3982731b9a8SJean-Christophe PLAGNIOL-VILLARD ed_t *ed_rm_list[2]; /* lists of all endpoints to be removed */ 3992731b9a8SJean-Christophe PLAGNIOL-VILLARD ed_t *ed_bulktail; /* last endpoint of bulk list */ 4002731b9a8SJean-Christophe PLAGNIOL-VILLARD ed_t *ed_controltail; /* last endpoint of control list */ 4012731b9a8SJean-Christophe PLAGNIOL-VILLARD int intrstatus; 4022731b9a8SJean-Christophe PLAGNIOL-VILLARD __u32 hc_control; /* copy of the hc control reg */ 4032731b9a8SJean-Christophe PLAGNIOL-VILLARD struct usb_device *dev[32]; 4042731b9a8SJean-Christophe PLAGNIOL-VILLARD struct virt_root_hub rh; 4052731b9a8SJean-Christophe PLAGNIOL-VILLARD 4062731b9a8SJean-Christophe PLAGNIOL-VILLARD const char *slot_name; 4072731b9a8SJean-Christophe PLAGNIOL-VILLARD } ohci_t; 40858b4048fSHans de Goede 409*fd09c205SSven Schwermer #if CONFIG_IS_ENABLED(DM_USB) 41058b4048fSHans de Goede extern struct dm_usb_ops ohci_usb_ops; 41158b4048fSHans de Goede 41258b4048fSHans de Goede int ohci_register(struct udevice *dev, struct ohci_regs *regs); 41358b4048fSHans de Goede int ohci_deregister(struct udevice *dev); 41458b4048fSHans de Goede #endif 415