__hc32 hwNextTD; /* Next TD Pointer */
__hc32 hwBE; /* Memory Buffer End Pointer */
- /* PSW is only for ISO */
-#define MAXPSW 1 /* hardware allows 8 */
+ /* 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 */
/*
* 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.
*/
__hc32 frame_no; /* current frame number */
__hc32 done_head; /* info returned for an interrupt */
u8 what [4]; /* spec only identifies 252 bytes :) */
} __attribute__ ((aligned(256)));
-#define ohci_frame_no(ohci) ((u16)hc32_to_cpup(ohci,&(ohci)->hcca->frame_no))
-
/*
* This is the structure of the OHCI controller's memory mapped I/O region.
* You must use readl() and writel() (in <asm/io.h>) to access these fields!!
#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
};
/*-------------------------------------------------------------------------*/
+/* 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 = USB_STATE_HALT;
+ 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 inline void periodic_reinit (struct ohci_hcd *ohci)
+static void periodic_reinit (struct ohci_hcd *ohci)
{
- u32 fi = ohci->fminterval & 0x0ffff;
+ 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);
}