Multiple fixes and improvements:

- Put "_LE_" into the register access macros to indicate little endian
byte order is expected by the hardware.
- Avoid using the bounce buffer when not strictly needed. Try to move
data directly using bus-space functions first.
- Ensure we preserve the reserved bits in the power down mode
register. Else the hardware goes into a non-recoverable state.
- Always use 32-bit access when writing or reading registers or FIFOs,
because the hardware is 32-bit oriented and don't really understand 8-
and 16-bit access.
- Correct writes to the memory address register. There is no need to
shift the register offset.
- Correct interval for interrupt endpoints.
- Optimise 90ns internal memory buffer read delay.
- Rename PDT into PTD, which is how the datasheet writes it.
- Add missing programming for activating host controller PTDs.

Sponsored by:	DARPA, AFRL
This commit is contained in:
Hans Petter Selasky 2014-05-27 10:01:19 +00:00
parent d32048bb6d
commit 21c85d9d3b
3 changed files with 525 additions and 365 deletions

File diff suppressed because it is too large Load Diff

View File

@ -32,7 +32,7 @@
#ifndef _SAF1761_OTG_H_
#define _SAF1761_OTG_H_
#define SOTG_MAX_DEVICES (USB_MIN_DEVICES + 1)
#define SOTG_MAX_DEVICES MIN(USB_MAX_DEVICES, 32)
#define SOTG_FS_MAX_PACKET_SIZE 64
#define SOTG_HS_MAX_PACKET_SIZE 512
#define SOTG_NUM_PORTS 2 /* one Device and one Host port */
@ -40,28 +40,26 @@
#define SOTG_DEVICE_PORT_NUM 2
#define SOTG_HOST_CHANNEL_MAX (3 * 32)
/* Macros used for reading and writing registers */
/* Macros used for reading and writing little endian registers */
#define SAF1761_READ_1(sc, reg) \
bus_space_read_1((sc)->sc_io_tag, (sc)->sc_io_hdl, (reg))
#define SAF1761_READ_2(sc, reg) ({ uint16_t _temp; \
_temp = bus_space_read_2((sc)->sc_io_tag, (sc)->sc_io_hdl, (reg)); \
le16toh(_temp); })
#define SAF1761_READ_4(sc, reg) ({ uint32_t _temp; \
#define SAF1761_READ_LE_4(sc, reg) ({ uint32_t _temp; \
_temp = bus_space_read_4((sc)->sc_io_tag, (sc)->sc_io_hdl, (reg)); \
le32toh(_temp); })
#define SAF1761_WRITE_1(sc, reg, data) \
bus_space_write_1((sc)->sc_io_tag, (sc)->sc_io_hdl, (reg), data)
#define SAF1761_WRITE_2(sc, reg, data) do { \
uint16_t _temp = (data); \
bus_space_write_2((sc)->sc_io_tag, (sc)->sc_io_hdl, (reg), htole16(_temp)); \
} while (0)
#define SAF1761_WRITE_4(sc, reg, data) do { \
#define SAF1761_WRITE_LE_4(sc, reg, data) do { \
uint32_t _temp = (data); \
bus_space_write_4((sc)->sc_io_tag, (sc)->sc_io_hdl, (reg), htole32(_temp)); \
} while (0)
/* 90ns delay macro */
#define SAF1761_90NS_DELAY(sc) do { \
(void) SAF1761_READ_LE_4(sc, SOTG_VEND_PROD_ID); \
(void) SAF1761_READ_LE_4(sc, SOTG_VEND_PROD_ID); \
(void) SAF1761_READ_LE_4(sc, SOTG_VEND_PROD_ID); \
(void) SAF1761_READ_LE_4(sc, SOTG_VEND_PROD_ID); \
} while (0)
struct saf1761_otg_softc;
struct saf1761_otg_td;
@ -147,7 +145,8 @@ struct saf1761_otg_softc {
uint32_t sc_intr_enable; /* enabled interrupts */
uint32_t sc_hw_mode; /* hardware mode */
uint8_t sc_bounce_buffer[1024] __aligned(4);
uint32_t sc_bounce_buffer[1024 / 4];
uint8_t sc_rt_addr; /* root HUB address */
uint8_t sc_dv_addr; /* device address */
uint8_t sc_conf; /* root HUB config */

View File

@ -34,10 +34,12 @@
/* Global registers */
#define SOTG_VEND_ID 0x370
#define SOTG_PROD_ID 0x372
#define SOTG_CTRL_SET 0x374
#define SOTG_CTRL_CLR 0x376
#define SOTG_VEND_PROD_ID 0x370
#define SOTG_VEND_ID(x) ((x) & 0xFFFF)
#define SOTG_PROD_ID(x) (((x) >> 16) & 0xFFFF)
#define SOTG_CTRL_SET_CLR 0x374
#define SOTG_CTRL_SET(x) ((x) & 0xFFFF)
#define SOTG_CTRL_CLR(x) (((x) << 16) & 0xFFFF0000)
#define SOTG_CTRL_OTG_DISABLE (1 << 10)
#define SOTG_CTRL_OTG_SE0_EN (1 << 9)
#define SOTG_CTRL_BDIS_ACON_EN (1 << 8)
@ -57,12 +59,15 @@
#define SOTG_STATUS_DP_SRP (1 << 2)
#define SOTG_STATUS_A_B_SESS_VLD (1 << 1)
#define SOTG_STATUS_VBUS_VLD (1 << 0)
#define SOTG_IRQ_LATCH_SET 0x37C
#define SOTG_IRQ_LATCH_CLR 0x37E
#define SOTG_IRQ_ENABLE_SET 0x380
#define SOTG_IRQ_ENABLE_CLR 0x382
#define SOTG_IRQ_RISE_SET 0x384
#define SOTG_IRQ_RISE_CLR 0x386
#define SOTG_IRQ_LATCH_SET_CLR 0x37C
#define SOTG_IRQ_LATCH_SET(x) ((x) & 0xFFFF)
#define SOTG_IRQ_LATCH_CLR(x) (((x) << 16) & 0xFFFF0000)
#define SOTG_IRQ_ENABLE_SET_CLR 0x380
#define SOTG_IRQ_ENABLE_SET(x) ((x) & 0xFFFF)
#define SOTG_IRQ_ENABLE_CLR(x) (((x) << 16) & 0xFFFF0000)
#define SOTG_IRQ_RISE_SET_CLR 0x384
#define SOTG_IRQ_RISE_SET(x) ((x) & 0xFFFF)
#define SOTG_IRQ_RISE_CLR(x) (((x) << 16) & 0xFFFF0000)
#define SOTG_IRQ_OTG_TMR_TIMEOUT (1 << 9)
#define SOTG_IRQ_B_SE0_SRP (1 << 8)
#define SOTG_IRQ_B_SESS_END (1 << 7)
@ -73,10 +78,12 @@
#define SOTG_IRQ_DP_SRP (1 << 2)
#define SOTG_IRQ_A_B_SESS_VLD (1 << 1)
#define SOTG_IRQ_VBUS_VLD (1 << 0)
#define SOTG_TIMER_LOW_SET 0x388
#define SOTG_TIMER_LOW_CLR 0x38A
#define SOTG_TIMER_HIGH_SET 0x38C
#define SOTG_TIMER_HIGH_CLR 0x38E
#define SOTG_TIMER_LOW_SET_CLR 0x388
#define SOTG_TIMER_LOW_SET(x) ((x) & 0xFFFF)
#define SOTG_TIMER_LOW_CLR(x) (((x) << 16) & 0xFFFF0000)
#define SOTG_TIMER_HIGH_SET_CLR 0x38C
#define SOTG_TIMER_HIGH_SET(x) ((x) & 0xFFFF)
#define SOTG_TIMER_HIGH_CLR(x) (((x) << 16) & 0xFFFF0000)
#define SOTG_TIMER_START_TMR (1U << 15)
#define SOTG_MEMORY_REG 0x33c
@ -94,13 +101,12 @@
#define SOTG_MODE_GLINTENA (1 << 3)
#define SOTG_MODE_WKUPCS (1 << 2)
#define SOTG_INTERRUPT_CFG 0x210
#define SOTG_INTERRUPT_CFG_DEBUG_SET (1 << 16)
#define SOTG_INTERRUPT_CFG_CDBGMOD (3 << 6)
#define SOTG_INTERRUPT_CFG_DDBGMODIN (3 << 4)
#define SOTG_INTERRUPT_CFG_DDBGMODOUT (3 << 2)
#define SOTG_INTERRUPT_CFG_INTLVL (1 << 1)
#define SOTG_INTERRUPT_CFG_INTPOL (1 << 0)
#define SOTG_DEBUG 0x212
#define SOTG_DEBUG_SET (1 << 0)
#define SOTG_DCINTERRUPT_EN 0x214
#define SOTG_HW_MODE_CTRL 0x300
#define SOTG_HW_MODE_CTRL_ALL_ATX_RESET (1 << 31)
@ -129,8 +135,8 @@
#define SOTG_CTRL_FUNC_STALL (1 << 0)
#define SOTG_DATA_PORT 0x220
#define SOTG_BUF_LENGTH 0x21C
#define SOTG_DCBUFFERSTATUS 0x21E
#define SOTG_DCBUFFERSTATUS_FILLED_MASK (3 << 0)
#define SOTG_BUF_LENGTH_BUFLEN_MASK 0xFFFF
#define SOTG_BUF_LENGTH_FILLED_MASK (3 << 16)
#define SOTG_EP_MAXPACKET 0x204
#define SOTG_EP_TYPE 0x208
#define SOTG_EP_TYPE_NOEMPPKT (1 << 4)
@ -176,6 +182,7 @@
/* Host controller specific registers */
#define SOTG_FRINDEX 0x002c
#define SOTG_CONFIGFLAG 0x0060
#define SOTG_CONFIGFLAG_ENABLE (1 << 0)
#define SOTG_PORTSC1 0x0064
@ -189,25 +196,26 @@
#define SOTG_PORTSC1_PED (1 << 2)
#define SOTG_PORTSC1_ECSC (1 << 1)
#define SOTG_PORTSC1_ECCS (1 << 0)
#define SOTG_PDT_DW0 0
#define SOTG_PDT_DW0_VALID 1U
#define SOTG_PDT_DW1 4
#define SOTG_PDT_DW2 8
#define SOTG_PDT_DW3 12
#define SOTG_PDT_DW3_ACTIVE (1U << 31)
#define SOTG_PDT_DW3_HALTED (1U << 30)
#define SOTG_PDT_DW3_ERRORS (3U << 28)
#define SOTG_PDT_DW3_CERR (3U << 23)
#define SOTG_PDT_DW3_XFER_COUNT 0x7FFF
#define SOTG_PDT_DW4 16
#define SOTG_PDT_DW5 20
#define SOTG_PDT_DW6 24
#define SOTG_PDT_DW7 28
#define SOTG_PTD_DW0 0
#define SOTG_PTD_DW0_VALID 1U
#define SOTG_PTD_DW1 4
#define SOTG_PTD_DW1_ENABLE_SPLIT (1 << 14)
#define SOTG_PTD_DW2 8
#define SOTG_PTD_DW3 12
#define SOTG_PTD_DW3_ACTIVE (1U << 31)
#define SOTG_PTD_DW3_HALTED (1U << 30)
#define SOTG_PTD_DW3_ERRORS (3U << 28)
#define SOTG_PTD_DW3_CERR (3U << 23)
#define SOTG_PTD_DW3_XFER_COUNT 0x7FFF
#define SOTG_PTD_DW4 16
#define SOTG_PTD_DW5 20
#define SOTG_PTD_DW6 24
#define SOTG_PTD_DW7 28
#define SOTG_DATA_ADDR(x) (0x1000 + (512 * (x)))
#define SOTG_ASYNC_PDT(x) (0xC00 + ((x) * 32))
#define SOTG_INTR_PDT(x) (0x800 + ((x) * 32))
#define SOTG_ISOC_PDT(x) (0x400 + ((x) * 32))
#define SOTG_PDT(x) (0x400 + ((x) * 32))
#define SOTG_ASYNC_PTD(x) (0xC00 + ((x) * 32))
#define SOTG_INTR_PTD(x) (0x800 + ((x) * 32))
#define SOTG_ISOC_PTD(x) (0x400 + ((x) * 32))
#define SOTG_PTD(x) (0x400 + ((x) * 32))
#define SOTG_HC_MEMORY_ADDR(x) (((x) - 0x400) >> 3)
#define SOTG_SW_RESET 0x30C
#define SOTG_SW_RESET_HC (1 << 1)
@ -237,5 +245,15 @@
#define SOTG_HCINTERRUPT_DMAEOTINT (1 << 3)
#define SOTG_HCINTERRUPT_SOFITLINT (1 << 1)
#define SOTG_HCINTERRUPT_ENABLE 0x314
#define SOTG_ATL_PTD_SKIP_PTD 0x154
#define SOTG_ATL_PTD_LAST_PTD 0x158
#define SOTG_INT_PTD_SKIP_PTD 0x144
#define SOTG_INT_PTD_LAST_PTD 0x148
#define SOTG_ISO_PTD_SKIP_PTD 0x134
#define SOTG_ISO_PTD_LAST_PTD 0x138
#define SOTG_HCBUFFERSTATUS 0x334
#define SOTG_HCBUFFERSTATUS_ISO_BUF_FILL (1 << 2)
#define SOTG_HCBUFFERSTATUS_INT_BUF_FILL (1 << 1)
#define SOTG_HCBUFFERSTATUS_ATL_BUF_FILL (1 << 0)
#endif /* _SAF1761_OTG_REG_H_ */