/*
* e.g. PCI controllers need this
*/
+
+#include <asm/io.h>
+
#ifdef CONFIG_SYS_OHCI_SWAP_REG_ACCESS
-# define ohci_readl(a) __swap_32(*((volatile u32 *)(a)))
-# define ohci_writel(a, b) (*((volatile u32 *)(b)) = __swap_32((volatile u32)a))
+# define ohci_readl(a) __swap_32(readl(a))
+# define ohci_writel(v, a) writel(__swap_32(v), a)
#else
-# define ohci_readl(a) (*((volatile u32 *)(a)))
-# define ohci_writel(a, b) (*((volatile u32 *)(b)) = ((volatile u32)a))
+# define ohci_readl(a) readl(a)
+# define ohci_writel(v, a) writel(v, a)
#endif /* CONFIG_SYS_OHCI_SWAP_REG_ACCESS */
+#if ARCH_DMA_MINALIGN > 16
+#define ED_ALIGNMENT ARCH_DMA_MINALIGN
+#else
+#define ED_ALIGNMENT 16
+#endif
+
+#if defined CONFIG_DM_USB && ARCH_DMA_MINALIGN > 32
+#define TD_ALIGNMENT ARCH_DMA_MINALIGN
+#else
+#define TD_ALIGNMENT 32
+#endif
+
/* functions for doing board or CPU specific setup/cleanup */
-extern int usb_board_init(void);
-extern int usb_board_stop(void);
-extern int usb_board_init_fail(void);
-
-extern int usb_cpu_init(void);
-extern int usb_cpu_stop(void);
-extern int usb_cpu_init_fail(void);
-
-
-static int cc_to_error[16] = {
-
-/* mapping of the OHCI CC status to error codes */
- /* No Error */ 0,
- /* CRC Error */ USB_ST_CRC_ERR,
- /* Bit Stuff */ USB_ST_BIT_ERR,
- /* Data Togg */ USB_ST_CRC_ERR,
- /* Stall */ USB_ST_STALLED,
- /* DevNotResp */ -1,
- /* PIDCheck */ USB_ST_BIT_ERR,
- /* UnExpPID */ USB_ST_BIT_ERR,
- /* DataOver */ USB_ST_BUF_ERR,
- /* DataUnder */ USB_ST_BUF_ERR,
- /* reservd */ -1,
- /* reservd */ -1,
- /* BufferOver */ USB_ST_BUF_ERR,
- /* BuffUnder */ USB_ST_BUF_ERR,
- /* Not Access */ -1,
- /* Not Access */ -1
-};
+int usb_board_stop(void);
-static const char *cc_to_string[16] = {
- "No Error",
- "CRC: Last data packet from endpoint contained a CRC error.",
- "BITSTUFFING: Last data packet from endpoint contained a bit " \
- "stuffing violation",
- "DATATOGGLEMISMATCH: Last packet from endpoint had data toggle PID\n" \
- "that did not match the expected value.",
- "STALL: TD was moved to the Done Queue because the endpoint returned" \
- " a STALL PID",
- "DEVICENOTRESPONDING: Device did not respond to token (IN) or did\n" \
- "not provide a handshake (OUT)",
- "PIDCHECKFAILURE: Check bits on PID from endpoint failed on data PID\n"\
- "(IN) or handshake (OUT)",
- "UNEXPECTEDPID: Receive PID was not valid when encountered or PID\n" \
- "value is not defined.",
- "DATAOVERRUN: The amount of data returned by the endpoint exceeded\n" \
- "either the size of the maximum data packet allowed\n" \
- "from the endpoint (found in MaximumPacketSize field\n" \
- "of ED) or the remaining buffer size.",
- "DATAUNDERRUN: The endpoint returned less than MaximumPacketSize\n" \
- "and that amount was not sufficient to fill the\n" \
- "specified buffer",
- "reserved1",
- "reserved2",
- "BUFFEROVERRUN: During an IN, HC received data from endpoint faster\n" \
- "than it could be written to system memory",
- "BUFFERUNDERRUN: During an OUT, HC could not retrieve data from\n" \
- "system memory fast enough to keep up with data USB " \
- "data rate.",
- "NOT ACCESSED: This code is set by software before the TD is placed" \
- "on a list to be processed by the HC.(1)",
- "NOT ACCESSED: This code is set by software before the TD is placed" \
- "on a list to be processed by the HC.(2)",
-};
+int usb_cpu_init(void);
+int usb_cpu_stop(void);
+int usb_cpu_init_fail(void);
/* ED States */
-
#define ED_NEW 0x00
#define ED_UNLINK 0x01
#define ED_OPER 0x02
struct usb_device *usb_dev;
void *purb;
__u32 unused[2];
-} __attribute__((aligned(16)));
+} __attribute__((aligned(ED_ALIGNMENT)));
typedef struct ed ed_t;
__u32 hwNextTD; /* Next TD Pointer */
__u32 hwBE; /* Memory Buffer End Pointer */
-/* #ifndef CONFIG_MPC5200 /\* this seems wrong *\/ */
__u16 hwPSW[MAXPSW];
-/* #endif */
__u8 unused;
__u8 index;
struct ed *ed;
__u32 data;
__u32 unused2[2];
-} __attribute__((aligned(32)));
+} __attribute__((aligned(TD_ALIGNMENT)));
typedef struct td td_t;
#define OHCI_ED_SKIP (1 << 14)
#define NUM_INTS 32 /* part of the OHCI standard */
struct ohci_hcca {
__u32 int_table[NUM_INTS]; /* Interrupt ED table */
-#if defined(CONFIG_MPC5200)
- __u16 pad1; /* set to 0 on each frame_no change */
- __u16 frame_no; /* current frame number */
-#else
__u16 frame_no; /* current frame number */
__u16 pad1; /* set to 0 on each frame_no change */
-#endif
__u32 done_head; /* info returned for an interrupt */
u8 reserved_for_hc[116];
} __attribute__((aligned(256)));
} urb_priv_t;
#define URB_DEL 1
+#define NUM_EDS 8 /* num of preallocated endpoint descriptors */
+
+#define NUM_TD 64 /* we need more TDs than EDs */
+
+#define NUM_INT_DEVS 8 /* num of ohci_dev structs for int endpoints */
+
+typedef struct ohci_device {
+ ed_t ed[NUM_EDS] __aligned(ED_ALIGNMENT);
+ td_t tds[NUM_TD] __aligned(TD_ALIGNMENT);
+ int ed_cnt;
+ int devnum;
+} ohci_dev_t;
+
/*
* This is the full ohci controller description
*
typedef struct ohci {
+ /* this allocates EDs for all possible endpoints */
+ struct ohci_device ohci_dev __aligned(TD_ALIGNMENT);
+ struct ohci_device int_dev[NUM_INT_DEVS] __aligned(TD_ALIGNMENT);
struct ohci_hcca *hcca; /* hcca */
/*dma_addr_t hcca_dma;*/
const char *slot_name;
} ohci_t;
-#define NUM_EDS 8 /* num of preallocated endpoint descriptors */
-
-struct ohci_device {
- ed_t ed[NUM_EDS];
- int ed_cnt;
-};
-
-/* hcd */
-/* endpoint */
-static int ep_link(ohci_t * ohci, ed_t * ed);
-static int ep_unlink(ohci_t * ohci, ed_t * ed);
-static ed_t * ep_add_ed(struct usb_device * usb_dev, unsigned long pipe,
- int interval, int load);
-
-/*-------------------------------------------------------------------------*/
-
-/* we need more TDs than EDs */
-#define NUM_TD 64
+#ifdef CONFIG_DM_USB
+extern struct dm_usb_ops ohci_usb_ops;
-/* +1 so we can align the storage */
-td_t gtd[NUM_TD+1];
-/* pointers to aligned storage */
-td_t *ptd;
-
-/* TDs ... */
-static inline struct td *
-td_alloc (struct usb_device *usb_dev)
-{
- int i;
- struct td *td;
-
- td = NULL;
- for (i = 0; i < NUM_TD; i++)
- {
- if (ptd[i].usb_dev == NULL)
- {
- td = &ptd[i];
- td->usb_dev = usb_dev;
- break;
- }
- }
-
- return td;
-}
-
-static inline void
-ed_free (struct ed *ed)
-{
- ed->usb_dev = NULL;
-}
+int ohci_register(struct udevice *dev, struct ohci_regs *regs);
+int ohci_deregister(struct udevice *dev);
+#endif