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:
parent
d32048bb6d
commit
21c85d9d3b
File diff suppressed because it is too large
Load Diff
@ -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 */
|
||||
|
@ -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_ */
|
||||
|
Loading…
Reference in New Issue
Block a user