Multiple DWC OTG host mode related fixes and improvements:

- Rework how we allocate and free USB host channels, so that we only
allocate a channel if there is a real packet going out on the USB
cable.

- Use BULK type for control data and status, due to instabilities in
the HW it appears.

- Split FIFO TX levels into one for the periodic FIFO and one for the
non-periodic FIFO.

- Use correct HFNUM mask when scheduling host transactions. The HFNUM
register does not count the full 16-bit range.

- Correct START/COMPLETION slot for TT transactions. For INTERRUPT and
ISOCHRONOUS type transactions the hardware always respects the ODDFRM
bit, which means we need to allocate multiple host channels when
processing such endpoints, to not miss any so-called complete split
opportunities.

- When doing ISOCHRONOUS OUT transfers through a TT send all data
payload in a single ALL-burst. This deacreases the likelyhood for
isochronous data underruns.

- Fixed unbalanced unlock in case of "dwc_otg_init_fifo()" failure.

- Increase interrupt priority.

MFC after:	2 weeks
This commit is contained in:
Hans Petter Selasky 2014-05-09 14:23:06 +00:00
parent d58c15339b
commit db4300da10
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=265777
4 changed files with 604 additions and 735 deletions

File diff suppressed because it is too large Load Diff

View File

@ -34,6 +34,8 @@
#define DWC_OTG_MAX_CHANNELS 16
#define DWC_OTG_MAX_ENDPOINTS 16
#define DWC_OTG_HOST_TIMER_RATE 10 /* ms */
#define DWC_OTG_TT_SLOT_MAX 8
#define DWC_OTG_SLOT_IDLE_MAX 4
#define DWC_OTG_READ_4(sc, reg) \
bus_space_read_4((sc)->sc_io_tag, (sc)->sc_io_hdl, reg)
@ -62,8 +64,8 @@ struct dwc_otg_td {
uint8_t tmr_res;
uint8_t tmr_val;
uint8_t ep_no;
uint8_t channel;
uint8_t tt_index; /* TT data */
uint8_t ep_type;
uint8_t channel[2];
uint8_t tt_start_slot; /* TT data */
uint8_t tt_complete_slot; /* TT data */
uint8_t tt_xactpos; /* TT data */
@ -86,6 +88,7 @@ struct dwc_otg_td {
uint8_t got_short:1;
uint8_t did_nak:1;
uint8_t tt_scheduled:1;
uint8_t tt_channel_tog:1;
};
struct dwc_otg_std_temp {
@ -105,7 +108,6 @@ struct dwc_otg_std_temp {
uint8_t setup_alt_next;
uint8_t did_stall;
uint8_t bulk_or_control;
uint8_t tt_index;
};
struct dwc_otg_config_desc {
@ -145,17 +147,11 @@ struct dwc_otg_profile {
};
struct dwc_otg_chan_state {
uint16_t allocated;
uint16_t wait_sof;
uint32_t hcint;
uint32_t tx_size;
uint8_t wait_sof;
uint8_t allocated;
uint8_t suspended;
};
struct dwc_otg_tt_info {
uint16_t bytes_used;
uint8_t slot_index;
uint8_t dummy;
uint16_t tx_p_size; /* periodic */
uint16_t tx_np_size; /* non-periodic */
};
struct dwc_otg_softc {
@ -177,7 +173,8 @@ struct dwc_otg_softc {
uint32_t sc_fifo_size;
uint32_t sc_tx_max_size;
uint32_t sc_tx_cur_size;
uint32_t sc_tx_cur_p_level; /* periodic */
uint32_t sc_tx_cur_np_level; /* non-periodic */
uint32_t sc_irq_mask;
uint32_t sc_last_rx_status;
uint32_t sc_out_ctl[DWC_OTG_MAX_ENDPOINTS];
@ -186,7 +183,6 @@ struct dwc_otg_softc {
uint32_t sc_tmr_val;
uint32_t sc_hprt_val;
struct dwc_otg_tt_info sc_tt_info[DWC_OTG_MAX_DEVICES];
uint16_t sc_active_rx_ep;
uint16_t sc_last_frame_num;
@ -194,6 +190,7 @@ struct dwc_otg_softc {
uint8_t sc_dev_ep_max;
uint8_t sc_dev_in_ep_max;
uint8_t sc_host_ch_max;
uint8_t sc_needsof;
uint8_t sc_rt_addr; /* root HUB address */
uint8_t sc_conf; /* root HUB config */
uint8_t sc_mode; /* mode of operation */

View File

@ -146,7 +146,7 @@ dwc_otg_attach(device_t dev)
device_set_ivars(sc->sc_otg.sc_bus.bdev, &sc->sc_otg.sc_bus);
err = bus_setup_intr(dev, sc->sc_otg.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
err = bus_setup_intr(dev, sc->sc_otg.sc_irq_res, INTR_TYPE_TTY | INTR_MPSAFE,
NULL, (driver_intr_t *)dwc_otg_interrupt, sc, &sc->sc_otg.sc_intr_hdl);
if (err) {
sc->sc_otg.sc_intr_hdl = NULL;

View File

@ -540,7 +540,7 @@
#define HCSPLT_XACTPOS_LAST 1
#define HCSPLT_XACTPOS_BEGIN 2
#define HCSPLT_XACTPOS_ALL 3
#define HCSPLT_XACTLEN_MAX 188 /* bytes */
#define HCSPLT_XACTLEN_BURST 1023 /* bytes */
#define HCSPLT_HUBADDR_SHIFT 7
#define HCSPLT_HUBADDR_MASK 0x00003f80
#define HCSPLT_PRTADDR_SHIFT 0
@ -555,6 +555,9 @@
HCINT_XACTERR | HCINT_NAK | HCINT_ACK | HCINT_NYET | \
HCINT_CHHLTD | HCINT_FRMOVRUN | \
HCINT_DATATGLERR)
#define HCINT_HCH_DONE_MASK \
(HCINT_ACK | HCINT_RETRY | HCINT_NYET | \
HCINT_ERRORS | HCINT_STALL | HCINT_SOFTWARE_ONLY)
#define HCINT_SOFTWARE_ONLY (1<<20) /* BSD only */
#define HCINT_DATATGLERR (1<<10)