X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fusb%2Fhost%2Fohci.h;h=22e1ac138ac0686bc4e72baba0d412d5f9c4022e;hb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;hp=70f32ef7271ec3185a584786b9502556262e6a4e;hpb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;p=linux-2.6.git diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 70f32ef72..22e1ac138 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -6,6 +6,14 @@ * * This file is licenced under the GPL. */ + +/* + * __hc32 and __hc16 are "Host Controller" types, they may be equivalent to + * __leXX (normally) or __beXX (given OHCI_BIG_ENDIAN), depending on the + * host controller implementation. + */ +typedef __u32 __bitwise __hc32; +typedef __u16 __bitwise __hc16; /* * OHCI Endpoint Descriptor (ED) ... holds TD queue @@ -15,21 +23,21 @@ * both EHCI and UHCI call similar structures a "QH". */ struct ed { - /* first fields are hardware-specified, le32 */ - __u32 hwINFO; /* endpoint config bitmap */ + /* first fields are hardware-specified */ + __hc32 hwINFO; /* endpoint config bitmap */ /* info bits defined by hcd */ -#define ED_DEQUEUE __constant_cpu_to_le32(1 << 27) +#define ED_DEQUEUE (1 << 27) /* info bits defined by the hardware */ -#define ED_ISO __constant_cpu_to_le32(1 << 15) -#define ED_SKIP __constant_cpu_to_le32(1 << 14) -#define ED_LOWSPEED __constant_cpu_to_le32(1 << 13) -#define ED_OUT __constant_cpu_to_le32(0x01 << 11) -#define ED_IN __constant_cpu_to_le32(0x02 << 11) - __u32 hwTailP; /* tail of TD list */ - __u32 hwHeadP; /* head of TD list (hc r/w) */ -#define ED_C __constant_cpu_to_le32(0x02) /* toggle carry */ -#define ED_H __constant_cpu_to_le32(0x01) /* halted */ - __u32 hwNextED; /* next ED in list */ +#define ED_ISO (1 << 15) +#define ED_SKIP (1 << 14) +#define ED_LOWSPEED (1 << 13) +#define ED_OUT (0x01 << 11) +#define ED_IN (0x02 << 11) + __hc32 hwTailP; /* tail of TD list */ + __hc32 hwHeadP; /* head of TD list (hc r/w) */ +#define ED_C (0x02) /* toggle carry */ +#define ED_H (0x01) /* halted */ + __hc32 hwNextED; /* next ED in list */ /* rest are purely for the driver's use */ dma_addr_t dma; /* addr of ED */ @@ -42,7 +50,6 @@ struct ed { /* create --> IDLE --> OPER --> ... --> IDLE --> destroy * usually: OPER --> UNLINK --> (IDLE | OPER) --> ... - * some special cases : OPER --> IDLE ... */ u8 state; /* ED_{IDLE,UNLINK,OPER} */ #define ED_IDLE 0x00 /* NOT linked to HC */ @@ -70,8 +77,8 @@ struct ed { * and 4.3.2 (iso) */ struct td { - /* first fields are hardware-specified, le32 */ - __u32 hwINFO; /* transfer info bitmask */ + /* first fields are hardware-specified */ + __hc32 hwINFO; /* transfer info bitmask */ /* hwINFO bits for both general and iso tds: */ #define TD_CC 0xf0000000 /* condition code */ @@ -100,13 +107,15 @@ struct td { /* (no hwINFO #defines yet for iso tds) */ - __u32 hwCBP; /* Current Buffer Pointer (or 0) */ - __u32 hwNextTD; /* Next TD Pointer */ - __u32 hwBE; /* Memory Buffer End Pointer */ + __hc32 hwCBP; /* Current Buffer Pointer (or 0) */ + __hc32 hwNextTD; /* Next TD Pointer */ + __hc32 hwBE; /* Memory Buffer End Pointer */ - /* PSW is only for ISO */ -#define MAXPSW 1 /* hardware allows 8 */ - __u16 hwPSW [MAXPSW]; + /* PSW is only for ISO. Only 1 PSW entry is used, but on + * big-endian PPC hardware that's the second entry. + */ +#define MAXPSW 2 + __hc16 hwPSW [MAXPSW]; /* rest are purely for the driver's use */ __u8 index; @@ -171,21 +180,19 @@ static const int cc_to_error [16] = { */ struct ohci_hcca { #define NUM_INTS 32 - __u32 int_table [NUM_INTS]; /* periodic schedule */ + __hc32 int_table [NUM_INTS]; /* periodic schedule */ /* * OHCI defines u16 frame_no, followed by u16 zero pad. * Since some processors can't do 16 bit bus accesses, - * portable access must be a 32 bit byteswapped access. + * portable access must be a 32 bits wide. */ - u32 frame_no; /* current frame number */ -#define OHCI_FRAME_NO(hccap) ((u16)le32_to_cpup(&(hccap)->frame_no)) - __u32 done_head; /* info returned for an interrupt */ + __hc32 frame_no; /* current frame number */ + __hc32 done_head; /* info returned for an interrupt */ u8 reserved_for_hc [116]; u8 what [4]; /* spec only identifies 252 bytes :) */ } __attribute__ ((aligned(256))); - /* * This is the structure of the OHCI controller's memory mapped I/O region. * You must use readl() and writel() (in ) to access these fields!! @@ -193,36 +200,36 @@ struct ohci_hcca { */ struct ohci_regs { /* control and status registers (section 7.1) */ - __u32 revision; - __u32 control; - __u32 cmdstatus; - __u32 intrstatus; - __u32 intrenable; - __u32 intrdisable; + __hc32 revision; + __hc32 control; + __hc32 cmdstatus; + __hc32 intrstatus; + __hc32 intrenable; + __hc32 intrdisable; /* memory pointers (section 7.2) */ - __u32 hcca; - __u32 ed_periodcurrent; - __u32 ed_controlhead; - __u32 ed_controlcurrent; - __u32 ed_bulkhead; - __u32 ed_bulkcurrent; - __u32 donehead; + __hc32 hcca; + __hc32 ed_periodcurrent; + __hc32 ed_controlhead; + __hc32 ed_controlcurrent; + __hc32 ed_bulkhead; + __hc32 ed_bulkcurrent; + __hc32 donehead; /* frame counters (section 7.3) */ - __u32 fminterval; - __u32 fmremaining; - __u32 fmnumber; - __u32 periodicstart; - __u32 lsthresh; + __hc32 fminterval; + __hc32 fmremaining; + __hc32 fmnumber; + __hc32 periodicstart; + __hc32 lsthresh; /* Root hub ports (section 7.4) */ struct ohci_roothub_regs { - __u32 a; - __u32 b; - __u32 status; + __hc32 a; + __hc32 b; + __hc32 status; #define MAX_ROOT_PORTS 15 /* maximum OHCI root hub ports (RH_A_NDP) */ - __u32 portstatus [MAX_ROOT_PORTS]; + __hc32 portstatus [MAX_ROOT_PORTS]; } roothub; /* and optional "legacy support" registers (appendix B) at 0x0100 */ @@ -343,7 +350,7 @@ struct ohci_hcd { /* * I/O memory used to communicate with the HC (dma-consistent) */ - struct ohci_regs *regs; + struct ohci_regs __iomem *regs; /* * main memory used to communicate with the HC (dma-consistent). @@ -359,6 +366,13 @@ struct ohci_hcd { struct ed *ed_controltail; /* last in ctrl list */ struct ed *periodic [NUM_INTS]; /* shadow int_table */ + /* + * OTG controllers and transceivers need software interaction; + * other external transceivers should be software-transparent + */ + struct otg_transceiver *transceiver; + unsigned power_budget; + /* * memory management for queue data structures */ @@ -380,32 +394,21 @@ struct ohci_hcd { unsigned long flags; /* for HC bugs */ #define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */ #define OHCI_QUIRK_SUPERIO 0x02 /* natsemi */ +#define OHCI_QUIRK_INITRESET 0x04 /* SiS, OPTi, ... */ +#define OHCI_BIG_ENDIAN 0x08 /* big endian HC */ +#define OHCI_QUIRK_ZFMICRO 0x10 /* Compaq ZFMicro chipset*/ // there are also chip quirks/bugs in init logic - /* - * framework state - */ - struct usb_hcd hcd; }; -#define hcd_to_ohci(hcd_ptr) container_of(hcd_ptr, struct ohci_hcd, hcd) - -/*-------------------------------------------------------------------------*/ - -static inline void disable (struct ohci_hcd *ohci) +/* convert between an hcd pointer and the corresponding ohci_hcd */ +static inline struct ohci_hcd *hcd_to_ohci (struct usb_hcd *hcd) { - ohci->hcd.state = USB_STATE_HALT; + return (struct ohci_hcd *) (hcd->hcd_priv); } - -#define FI 0x2edf /* 12000 bits per frame (-1) */ -#define DEFAULT_FMINTERVAL ((((6 * (FI - 210)) / 7) << 16) | FI) -#define LSTHRESH 0x628 /* lowspeed bit threshold */ - -static inline void periodic_reinit (struct ohci_hcd *ohci) +static inline struct usb_hcd *ohci_to_hcd (const struct ohci_hcd *ohci) { - writel (ohci->fminterval, &ohci->regs->fminterval); - writel (((9 * FI) / 10) & 0x3fff, &ohci->regs->periodicstart); - writel (LSTHRESH, &ohci->regs->lsthresh); + return container_of ((void *) ohci, struct usb_hcd, hcd_priv); } /*-------------------------------------------------------------------------*/ @@ -415,13 +418,13 @@ static inline void periodic_reinit (struct ohci_hcd *ohci) #endif /* DEBUG */ #define ohci_dbg(ohci, fmt, args...) \ - dev_dbg ((ohci)->hcd.self.controller , fmt , ## args ) + dev_dbg (ohci_to_hcd(ohci)->self.controller , fmt , ## args ) #define ohci_err(ohci, fmt, args...) \ - dev_err ((ohci)->hcd.self.controller , fmt , ## args ) + dev_err (ohci_to_hcd(ohci)->self.controller , fmt , ## args ) #define ohci_info(ohci, fmt, args...) \ - dev_info ((ohci)->hcd.self.controller , fmt , ## args ) + dev_info (ohci_to_hcd(ohci)->self.controller , fmt , ## args ) #define ohci_warn(ohci, fmt, args...) \ - dev_warn ((ohci)->hcd.self.controller , fmt , ## args ) + dev_warn (ohci_to_hcd(ohci)->self.controller , fmt , ## args ) #ifdef OHCI_VERBOSE_DEBUG # define ohci_vdbg ohci_dbg @@ -429,3 +432,206 @@ static inline void periodic_reinit (struct ohci_hcd *ohci) # define ohci_vdbg(ohci, fmt, args...) do { } while (0) #endif +/*-------------------------------------------------------------------------*/ + +/* + * While most USB host controllers implement their registers and + * in-memory communication descriptors in little-endian format, + * a minority (notably the IBM STB04XXX and the Motorola MPC5200 + * processors) implement them in big endian format. + * + * This attempts to support either format at compile time without a + * runtime penalty, or both formats with the additional overhead + * of checking a flag bit. + */ + +#ifdef CONFIG_USB_OHCI_BIG_ENDIAN + +#ifdef CONFIG_USB_OHCI_LITTLE_ENDIAN +#define big_endian(ohci) (ohci->flags & OHCI_BIG_ENDIAN) /* either */ +#else +#define big_endian(ohci) 1 /* only big endian */ +#endif + +/* + * Big-endian read/write functions are arch-specific. + * Other arches can be added if/when they're needed. + */ +#if defined(CONFIG_PPC) +#define readl_be(addr) in_be32((__force unsigned *)addr) +#define writel_be(val, addr) out_be32((__force unsigned *)addr, val) +#endif + +static inline unsigned int ohci_readl (const struct ohci_hcd *ohci, + __hc32 __iomem * regs) +{ + return big_endian(ohci) ? readl_be (regs) : readl ((__force u32 *)regs); +} + +static inline void ohci_writel (const struct ohci_hcd *ohci, + const unsigned int val, __hc32 __iomem *regs) +{ + big_endian(ohci) ? writel_be (val, regs) : + writel (val, (__force u32 *)regs); +} + +#else /* !CONFIG_USB_OHCI_BIG_ENDIAN */ + +#define big_endian(ohci) 0 /* only little endian */ + +#ifdef CONFIG_ARCH_LH7A404 + /* Marc Singer: at the time this code was written, the LH7A404 + * had a problem reading the USB host registers. This + * implementation of the ohci_readl function performs the read + * twice as a work-around. + */ +static inline unsigned int +ohci_readl (const struct ohci_hcd *ohci, const __hc32 *regs) +{ + *(volatile __force unsigned int*) regs; + return *(volatile __force unsigned int*) regs; +} +#else + /* Standard version of ohci_readl uses standard, platform + * specific implementation. */ +static inline unsigned int +ohci_readl (const struct ohci_hcd *ohci, __hc32 __iomem * regs) +{ + return readl(regs); +} +#endif + +static inline void ohci_writel (const struct ohci_hcd *ohci, + const unsigned int val, __hc32 __iomem *regs) +{ + writel (val, regs); +} + +#endif /* !CONFIG_USB_OHCI_BIG_ENDIAN */ + +/*-------------------------------------------------------------------------*/ + +/* cpu to ohci */ +static inline __hc16 cpu_to_hc16 (const struct ohci_hcd *ohci, const u16 x) +{ + return big_endian(ohci) ? (__force __hc16)cpu_to_be16(x) : (__force __hc16)cpu_to_le16(x); +} + +static inline __hc16 cpu_to_hc16p (const struct ohci_hcd *ohci, const u16 *x) +{ + return big_endian(ohci) ? cpu_to_be16p(x) : cpu_to_le16p(x); +} + +static inline __hc32 cpu_to_hc32 (const struct ohci_hcd *ohci, const u32 x) +{ + return big_endian(ohci) ? (__force __hc32)cpu_to_be32(x) : (__force __hc32)cpu_to_le32(x); +} + +static inline __hc32 cpu_to_hc32p (const struct ohci_hcd *ohci, const u32 *x) +{ + return big_endian(ohci) ? cpu_to_be32p(x) : cpu_to_le32p(x); +} + +/* ohci to cpu */ +static inline u16 hc16_to_cpu (const struct ohci_hcd *ohci, const __hc16 x) +{ + return big_endian(ohci) ? be16_to_cpu((__force __be16)x) : le16_to_cpu((__force __le16)x); +} + +static inline u16 hc16_to_cpup (const struct ohci_hcd *ohci, const __hc16 *x) +{ + return big_endian(ohci) ? be16_to_cpup((__force __be16 *)x) : le16_to_cpup((__force __le16 *)x); +} + +static inline u32 hc32_to_cpu (const struct ohci_hcd *ohci, const __hc32 x) +{ + return big_endian(ohci) ? be32_to_cpu((__force __be32)x) : le32_to_cpu((__force __le32)x); +} + +static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) +{ + return big_endian(ohci) ? be32_to_cpup((__force __be32 *)x) : le32_to_cpup((__force __le32 *)x); +} + +/*-------------------------------------------------------------------------*/ + +/* HCCA frame number is 16 bits, but is accessed as 32 bits since not all + * hardware handles 16 bit reads. That creates a different confusion on + * some big-endian SOC implementations. Same thing happens with PSW access. + */ + +#ifdef CONFIG_STB03xxx +#define OHCI_BE_FRAME_NO_SHIFT 16 +#else +#define OHCI_BE_FRAME_NO_SHIFT 0 +#endif + +static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) +{ + u32 tmp; + if (big_endian(ohci)) { + tmp = be32_to_cpup((__force __be32 *)&ohci->hcca->frame_no); + tmp >>= OHCI_BE_FRAME_NO_SHIFT; + } else + tmp = le32_to_cpup((__force __le32 *)&ohci->hcca->frame_no); + + return (u16)tmp; +} + +static inline __hc16 *ohci_hwPSWp(const struct ohci_hcd *ohci, + const struct td *td, int index) +{ + return (__hc16 *)(big_endian(ohci) ? + &td->hwPSW[index ^ 1] : &td->hwPSW[index]); +} + +static inline u16 ohci_hwPSW(const struct ohci_hcd *ohci, + const struct td *td, int index) +{ + return hc16_to_cpup(ohci, ohci_hwPSWp(ohci, td, index)); +} + +/*-------------------------------------------------------------------------*/ + +static inline void disable (struct ohci_hcd *ohci) +{ + ohci_to_hcd(ohci)->state = HC_STATE_HALT; +} + +#define FI 0x2edf /* 12000 bits per frame (-1) */ +#define FSMP(fi) (0x7fff & ((6 * ((fi) - 210)) / 7)) +#define FIT (1 << 31) +#define LSTHRESH 0x628 /* lowspeed bit threshold */ + +static void periodic_reinit (struct ohci_hcd *ohci) +{ + u32 fi = ohci->fminterval & 0x03fff; + u32 fit = ohci_readl(ohci, &ohci->regs->fminterval) & FIT; + + ohci_writel (ohci, (fit ^ FIT) | ohci->fminterval, + &ohci->regs->fminterval); + ohci_writel (ohci, ((9 * fi) / 10) & 0x3fff, + &ohci->regs->periodicstart); +} + +/* AMD-756 (D2 rev) reports corrupt register contents in some cases. + * The erratum (#4) description is incorrect. AMD's workaround waits + * till some bits (mostly reserved) are clear; ok for all revs. + */ +#define read_roothub(hc, register, mask) ({ \ + u32 temp = ohci_readl (hc, &hc->regs->roothub.register); \ + if (temp == -1) \ + disable (hc); \ + else if (hc->flags & OHCI_QUIRK_AMD756) \ + while (temp & mask) \ + temp = ohci_readl (hc, &hc->regs->roothub.register); \ + temp; }) + +static u32 roothub_a (struct ohci_hcd *hc) + { return read_roothub (hc, a, 0xfc0fe000); } +static inline u32 roothub_b (struct ohci_hcd *hc) + { return ohci_readl (hc, &hc->regs->roothub.b); } +static inline u32 roothub_status (struct ohci_hcd *hc) + { return ohci_readl (hc, &hc->regs->roothub.status); } +static u32 roothub_portstatus (struct ohci_hcd *hc, int i) + { return read_roothub (hc, portstatus [i], 0xffe0fce0); }