Fixes for ISP/SAF1761 host mode:

- Make the USB hardware skip PTDs which are not allocated.
- Peek host memory twice. Sometimes the PTD status is incorrectly
returned as zero.
- Ensure the host channel is always freed when software TD
is completing.
- Add correct configuration of interrupt polarity and type.
- Set CERR to 2 for asynchronous traffic to avoid having to
reactivate the PTD when a NAK token is received.
- Fix detection of STALL PID.

Sponsored by:	DARPA, AFRL
This commit is contained in:
Hans Petter Selasky 2014-05-28 16:28:22 +00:00
parent bdec45e2bc
commit 4272b84663
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=266812
3 changed files with 133 additions and 64 deletions

View File

@ -252,25 +252,24 @@ saf1761_host_channel_free(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t
if (td->channel >= SOTG_HOST_CHANNEL_MAX)
return;
/* disable channel */
SAF1761_WRITE_LE_4(sc, SOTG_PTD(td->channel) + SOTG_PTD_DW3, 0);
SAF1761_WRITE_LE_4(sc, SOTG_PTD(td->channel) + SOTG_PTD_DW0, 0);
switch (td->ep_type) {
case UE_INTERRUPT:
x = td->channel - 32;
sc->sc_host_intr_map &= ~(1 << x);
td->channel = SOTG_HOST_CHANNEL_MAX;
sc->sc_host_intr_map &= ~(1 << x);
SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD, ~sc->sc_host_intr_map);
break;
case UE_ISOCHRONOUS:
x = td->channel;
sc->sc_host_isoc_map &= ~(1 << x);
td->channel = SOTG_HOST_CHANNEL_MAX;
sc->sc_host_isoc_map &= ~(1 << x);
SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD, ~sc->sc_host_isoc_map);
break;
default:
x = td->channel - 64;
sc->sc_host_async_map &= ~(1 << x);
td->channel = SOTG_HOST_CHANNEL_MAX;
sc->sc_host_async_map &= ~(1 << x);
SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD, ~sc->sc_host_async_map);
break;
}
}
@ -401,19 +400,16 @@ saf1761_host_setup_tx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td)
pdt_addr = SOTG_PTD(td->channel);
status = saf1761_peek_host_memory_le_4(sc, pdt_addr + SOTG_PTD_DW3);
if (status == 0)
status = saf1761_peek_host_memory_le_4(sc, pdt_addr + SOTG_PTD_DW3);
DPRINTFN(5, "STATUS=0x%08x\n", status);
if (status & SOTG_PTD_DW3_ACTIVE) {
goto busy;
} else if (status & SOTG_PTD_DW3_HALTED) {
td->error_stall = 1;
td->error_any = 1;
} else if (status & SOTG_PTD_DW3_ERRORS) {
td->error_any = 1;
}
count = (status & SOTG_PTD_DW3_XFER_COUNT);
saf1761_host_channel_free(sc, td);
goto complete;
}
if (saf1761_host_channel_alloc(sc, td))
@ -435,7 +431,7 @@ saf1761_host_setup_tx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td)
SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW5, 0);
SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW4, 0);
temp = SOTG_PTD_DW3_ACTIVE | (td->toggle << 25) | SOTG_PTD_DW3_CERR;
temp = SOTG_PTD_DW3_ACTIVE | (td->toggle << 25) | SOTG_PTD_DW3_CERR_3;
SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW3, temp);
temp = SOTG_HC_MEMORY_ADDR(SOTG_DATA_ADDR(td->channel)) << 8;
@ -450,10 +446,14 @@ saf1761_host_setup_tx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td)
SOTG_PTD_DW0_VALID;
SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW0, temp);
/* activate PTD */
SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD, ~sc->sc_host_async_map);
td->toggle = 1;
busy:
return (1); /* busy */
complete:
saf1761_host_channel_free(sc, td);
return (0); /* complete */
}
@ -471,15 +471,16 @@ saf1761_host_bulk_data_rx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t
pdt_addr = SOTG_PTD(td->channel);
status = saf1761_peek_host_memory_le_4(sc, pdt_addr + SOTG_PTD_DW3);
if (status == 0)
status = saf1761_peek_host_memory_le_4(sc, pdt_addr + SOTG_PTD_DW3);
DPRINTFN(5, "STATUS=0x%08x\n", status);
if (status & SOTG_PTD_DW3_ACTIVE) {
goto busy;
} else if (status & SOTG_PTD_DW3_HALTED) {
td->error_stall = 1;
td->error_any = 1;
goto complete;
} else if (status & SOTG_PTD_DW3_ERRORS) {
if (!(status & SOTG_PTD_DW3_ERRORS))
td->error_stall = 1;
td->error_any = 1;
goto complete;
}
@ -509,14 +510,13 @@ saf1761_host_bulk_data_rx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t
saf1761_read_host_memory(sc, td, count);
saf1761_host_channel_free(sc, td);
/* check if we are complete */
if ((td->remainder == 0) || got_short) {
if (td->short_pkt)
goto complete;
/* else need to receive a zero length packet */
}
saf1761_host_channel_free(sc, td);
}
if (saf1761_host_channel_alloc(sc, td))
goto busy;
@ -536,10 +536,11 @@ saf1761_host_bulk_data_rx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t
SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW5, 0);
SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW4, 0);
temp = SOTG_PTD_DW3_ACTIVE | (td->toggle << 25) | SOTG_PTD_DW3_CERR;
temp = SOTG_PTD_DW3_ACTIVE | (td->toggle << 25) |
SOTG_PTD_DW3_CERR_2;
SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW3, temp);
temp = SOTG_HC_MEMORY_ADDR(SOTG_DATA_ADDR(td->channel)) << 8;
temp = (SOTG_HC_MEMORY_ADDR(SOTG_DATA_ADDR(td->channel)) << 8);
SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW2, temp);
temp = td->dw1_value | (1 << 10) /* IN-PID */ | (td->ep_index >> 1);
@ -550,9 +551,13 @@ saf1761_host_bulk_data_rx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t
(td->max_packet_size << 3) /* transfer count */ |
SOTG_PTD_DW0_VALID;
SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW0, temp);
/* activate PTD */
SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD, ~sc->sc_host_async_map);
busy:
return (1); /* busy */
complete:
saf1761_host_channel_free(sc, td);
return (0); /* complete */
}
@ -569,25 +574,26 @@ saf1761_host_bulk_data_tx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t
pdt_addr = SOTG_PTD(td->channel);
status = saf1761_peek_host_memory_le_4(sc, pdt_addr + SOTG_PTD_DW3);
if (status == 0)
status = saf1761_peek_host_memory_le_4(sc, pdt_addr + SOTG_PTD_DW3);
DPRINTFN(5, "STATUS=0x%08x\n", status);
if (status & SOTG_PTD_DW3_ACTIVE) {
goto busy;
} else if (status & SOTG_PTD_DW3_HALTED) {
td->error_stall = 1;
td->error_any = 1;
} else if (status & SOTG_PTD_DW3_ERRORS) {
if (!(status & SOTG_PTD_DW3_ERRORS))
td->error_stall = 1;
td->error_any = 1;
goto complete;
}
saf1761_host_channel_free(sc, td);
/* check remainder */
if (td->remainder == 0) {
if (td->short_pkt)
goto complete;
/* else we need to transmit a short packet */
}
saf1761_host_channel_free(sc, td);
}
if (saf1761_host_channel_alloc(sc, td))
goto busy;
@ -616,10 +622,11 @@ saf1761_host_bulk_data_tx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t
SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW5, 0);
SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW4, 0);
temp = SOTG_PTD_DW3_ACTIVE | (td->toggle << 25) | SOTG_PTD_DW3_CERR;
temp = SOTG_PTD_DW3_ACTIVE | (td->toggle << 25) |
SOTG_PTD_DW3_CERR_2;
SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW3, temp);
temp = SOTG_HC_MEMORY_ADDR(SOTG_DATA_ADDR(td->channel)) << 8;
temp = (SOTG_HC_MEMORY_ADDR(SOTG_DATA_ADDR(td->channel)) << 8);
SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW2, temp);
temp = td->dw1_value | (0 << 10) /* OUT-PID */ | (td->ep_index >> 1);
@ -631,10 +638,14 @@ saf1761_host_bulk_data_tx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t
SOTG_PTD_DW0_VALID;
SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW0, temp);
/* activate PTD */
SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD, ~sc->sc_host_async_map);
td->toggle ^= 1;
busy:
return (1); /* busy */
complete:
saf1761_host_channel_free(sc, td);
return (0); /* complete */
}
@ -652,16 +663,19 @@ saf1761_host_intr_data_rx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t
pdt_addr = SOTG_PTD(td->channel);
status = saf1761_peek_host_memory_le_4(sc, pdt_addr + SOTG_PTD_DW3);
if (status == 0)
status = saf1761_peek_host_memory_le_4(sc, pdt_addr + SOTG_PTD_DW3);
DPRINTFN(5, "STATUS=0x%08x\n", status);
if (status & SOTG_PTD_DW3_ACTIVE) {
goto busy;
} else if (status & SOTG_PTD_DW3_HALTED) {
td->error_stall = 1;
if (!(status & SOTG_PTD_DW3_ERRORS))
td->error_stall = 1;
td->error_any = 1;
goto complete;
}
count = (status & SOTG_PTD_DW3_XFER_COUNT);
got_short = 0;
@ -688,14 +702,13 @@ saf1761_host_intr_data_rx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t
saf1761_read_host_memory(sc, td, count);
saf1761_host_channel_free(sc, td);
/* check if we are complete */
if ((td->remainder == 0) || got_short) {
if (td->short_pkt)
goto complete;
/* else need to receive a zero length packet */
}
saf1761_host_channel_free(sc, td);
}
if (saf1761_host_channel_alloc(sc, td))
goto busy;
@ -719,7 +732,7 @@ saf1761_host_intr_data_rx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t
temp = (1U << td->uframe); /* start split */
SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW4, temp);
temp = SOTG_PTD_DW3_ACTIVE | (td->toggle << 25) | SOTG_PTD_DW3_CERR;
temp = SOTG_PTD_DW3_ACTIVE | (td->toggle << 25) | SOTG_PTD_DW3_CERR_3;
SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW3, temp);
temp = (SOTG_HC_MEMORY_ADDR(SOTG_DATA_ADDR(td->channel)) << 8) | (td->interval & 0xF8);
@ -733,9 +746,13 @@ saf1761_host_intr_data_rx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t
(td->max_packet_size << 3) /* transfer count */ |
SOTG_PTD_DW0_VALID;
SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW0, temp);
/* activate PTD */
SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD, ~sc->sc_host_intr_map);
busy:
return (1); /* busy */
complete:
saf1761_host_channel_free(sc, td);
return (0); /* complete */
}
@ -752,23 +769,27 @@ saf1761_host_intr_data_tx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t
pdt_addr = SOTG_PTD(td->channel);
status = saf1761_peek_host_memory_le_4(sc, pdt_addr + SOTG_PTD_DW3);
if (status == 0)
status = saf1761_peek_host_memory_le_4(sc, pdt_addr + SOTG_PTD_DW3);
DPRINTFN(5, "STATUS=0x%08x\n", status);
if (status & SOTG_PTD_DW3_ACTIVE) {
goto busy;
} else if (status & SOTG_PTD_DW3_HALTED) {
td->error_stall = 1;
if (!(status & SOTG_PTD_DW3_ERRORS))
td->error_stall = 1;
td->error_any = 1;
goto complete;
}
saf1761_host_channel_free(sc, td);
/* check remainder */
if (td->remainder == 0) {
if (td->short_pkt)
goto complete;
/* else we need to transmit a short packet */
}
saf1761_host_channel_free(sc, td);
}
if (saf1761_host_channel_alloc(sc, td))
goto busy;
@ -801,7 +822,7 @@ saf1761_host_intr_data_tx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t
temp = (1U << td->uframe); /* start split */
SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW4, temp);
temp = SOTG_PTD_DW3_ACTIVE | (td->toggle << 25) | SOTG_PTD_DW3_CERR;
temp = SOTG_PTD_DW3_ACTIVE | (td->toggle << 25) | SOTG_PTD_DW3_CERR_3;
SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW3, temp);
temp = (SOTG_HC_MEMORY_ADDR(SOTG_DATA_ADDR(td->channel)) << 8) | (td->interval & 0xF8);
@ -816,22 +837,32 @@ saf1761_host_intr_data_tx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t
SOTG_PTD_DW0_VALID;
SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW0, temp);
/* activate PTD */
SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD, ~sc->sc_host_intr_map);
td->toggle ^= 1;
busy:
return (1); /* busy */
complete:
saf1761_host_channel_free(sc, td);
return (0); /* complete */
}
static uint8_t
saf1761_host_isoc_data_rx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td)
{
/* activate PTD */
SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD, ~sc->sc_host_isoc_map);
return (1); /* busy */
}
static uint8_t
saf1761_host_isoc_data_tx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td)
{
/* activate PTD */
SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD, ~sc->sc_host_isoc_map);
return (1); /* busy */
}
@ -1319,10 +1350,13 @@ saf1761_otg_interrupt(struct saf1761_otg_softc *sc)
SAF1761_READ_LE_4(sc, SOTG_FRAME_NUM),
SAF1761_READ_LE_4(sc, SOTG_FRINDEX));
(void) SAF1761_READ_LE_4(sc, SOTG_ATL_PTD_DONE_PTD);
(void) SAF1761_READ_LE_4(sc, SOTG_INT_PTD_DONE_PTD);
(void) SAF1761_READ_LE_4(sc, SOTG_ISO_PTD_DONE_PTD);
/* update VBUS and ID bits, if any */
if (status & SOTG_DCINTERRUPT_IEVBUS) {
if (status & SOTG_DCINTERRUPT_IEVBUS)
saf1761_otg_update_vbus(sc);
}
if (status & SOTG_DCINTERRUPT_IEBRST) {
/* unlock device */
@ -1431,7 +1465,8 @@ saf1761_otg_setup_standard_chain(struct usb_xfer *xfer)
temp.td = NULL;
temp.td_next = xfer->td_start[0];
temp.offset = 0;
temp.setup_alt_next = xfer->flags_int.short_frames_ok;
temp.setup_alt_next = xfer->flags_int.short_frames_ok ||
xfer->flags_int.isochronous_xfr;
temp.did_stall = !xfer->flags_int.control_stall;
is_host = (xfer->xroot->udev->flags.usb_mode == USB_MODE_HOST);
@ -1732,7 +1767,8 @@ saf1761_otg_standard_done_sub(struct usb_xfer *xfer)
}
/* Check for short transfer */
if (len > 0) {
if (xfer->flags_int.short_frames_ok) {
if (xfer->flags_int.short_frames_ok ||
xfer->flags_int.isochronous_xfr) {
/* follow alt next */
if (td->alt_next) {
td = td->obj_next;
@ -2048,12 +2084,13 @@ saf1761_otg_init(struct saf1761_otg_softc *sc)
SAF1761_WRITE_LE_4(sc, SOTG_MODE, SOTG_MODE_GLINTENA |
SOTG_MODE_CLKAON | SOTG_MODE_WKUPCS);
sc->sc_interrupt_cfg |=
SOTG_INTERRUPT_CFG_CDBGMOD |
SOTG_INTERRUPT_CFG_DDBGMODIN |
SOTG_INTERRUPT_CFG_DDBGMODOUT;
/* set default values */
SAF1761_WRITE_LE_4(sc, SOTG_INTERRUPT_CFG,
SOTG_INTERRUPT_CFG_CDBGMOD |
SOTG_INTERRUPT_CFG_DDBGMODIN |
SOTG_INTERRUPT_CFG_DDBGMODOUT |
sc->sc_interrupt_cfg);
SAF1761_WRITE_LE_4(sc, SOTG_INTERRUPT_CFG, sc->sc_interrupt_cfg);
/* enable VBUS and ID interrupt */
SAF1761_WRITE_LE_4(sc, SOTG_IRQ_ENABLE_SET_CLR,
@ -2099,15 +2136,15 @@ saf1761_otg_init(struct saf1761_otg_softc *sc)
DPRINTF("USBCMD=0x%08x\n", SAF1761_READ_LE_4(sc, SOTG_USBCMD));
/* activate all PTDs */
/* make HC scan all PTDs */
SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_LAST_PTD, (1 << 31));
SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_LAST_PTD, (1 << 31));
SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_LAST_PTD, (1 << 31));
/* skip no PTDs */
SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD, 0);
SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD, 0);
SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD, 0);
/* skip all PTDs by default */
SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD, -1U);
SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD, -1U);
SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD, -1U);
/* activate all PTD types */
SAF1761_WRITE_LE_4(sc, SOTG_HCBUFFERSTATUS,
@ -2115,6 +2152,16 @@ saf1761_otg_init(struct saf1761_otg_softc *sc)
SOTG_HCBUFFERSTATUS_INT_BUF_FILL |
SOTG_HCBUFFERSTATUS_ATL_BUF_FILL);
/* we don't use the AND mask */
SAF1761_WRITE_LE_4(sc, SOTG_ISO_IRQ_MASK_AND, 0);
SAF1761_WRITE_LE_4(sc, SOTG_INT_IRQ_MASK_AND, 0);
SAF1761_WRITE_LE_4(sc, SOTG_ATL_IRQ_MASK_AND, 0);
/* enable all PTD OR interrupts by default */
SAF1761_WRITE_LE_4(sc, SOTG_ISO_IRQ_MASK_OR, -1U);
SAF1761_WRITE_LE_4(sc, SOTG_INT_IRQ_MASK_OR, -1U);
SAF1761_WRITE_LE_4(sc, SOTG_ATL_IRQ_MASK_OR, -1U);
/* enable HC interrupts */
SAF1761_WRITE_LE_4(sc, SOTG_HCINTERRUPT_ENABLE,
SOTG_HCINTERRUPT_OTG_IRQ |

View File

@ -160,12 +160,14 @@ saf1761_otg_fdt_attach(device_t dev)
if (OF_getprop(ofw_bus_get_node(dev), "int-polarity",
&param, sizeof(param)) > 0) {
sc->sc_interrupt_cfg |= SOTG_INTERRUPT_CFG_INTPOL;
sc->sc_hw_mode |= SOTG_HW_MODE_CTRL_INTR_POL;
}
/* get IRQ level triggering */
if (OF_getprop(ofw_bus_get_node(dev), "int-level",
&param, sizeof(param)) > 0) {
sc->sc_interrupt_cfg |= SOTG_INTERRUPT_CFG_INTLVL;
sc->sc_hw_mode |= SOTG_HW_MODE_CTRL_INTR_LEVEL;
}
/* initialise some bus fields */
@ -182,23 +184,30 @@ saf1761_otg_fdt_attach(device_t dev)
sc->sc_io_res =
bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
if (!sc->sc_io_res) {
if (sc->sc_io_res == NULL)
goto error;
}
sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
sc->sc_io_size = rman_get_size(sc->sc_io_res);
rid = 0;
/* try to allocate the HC interrupt first */
rid = 1;
sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_SHAREABLE | RF_ACTIVE);
if (sc->sc_irq_res == NULL) {
goto error;
/* try to allocate a common IRQ second */
rid = 0;
sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_SHAREABLE | RF_ACTIVE);
if (sc->sc_irq_res == NULL)
goto error;
}
sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
if (!(sc->sc_bus.bdev)) {
if (sc->sc_bus.bdev == NULL)
goto error;
}
device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,

View File

@ -84,7 +84,7 @@
#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_TIMER_HIGH_START (1U << 15)
#define SOTG_MEMORY_REG 0x33c
/* Peripheral controller specific registers */
@ -102,9 +102,9 @@
#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_CDBGMOD (1 << 6) /* ACK only */
#define SOTG_INTERRUPT_CFG_DDBGMODIN (1 << 4) /* ACK only */
#define SOTG_INTERRUPT_CFG_DDBGMODOUT (1 << 2) /* ACK and NYET only */
#define SOTG_INTERRUPT_CFG_INTLVL (1 << 1)
#define SOTG_INTERRUPT_CFG_INTPOL (1 << 0)
#define SOTG_DCINTERRUPT_EN 0x214
@ -201,11 +201,15 @@
#define SOTG_PTD_DW1 4
#define SOTG_PTD_DW1_ENABLE_SPLIT (1 << 14)
#define SOTG_PTD_DW2 8
#define SOTG_PTD_DW2_RL (0xf << 25)
#define SOTG_PTD_DW3 12
#define SOTG_PTD_DW3_NRL (0xf << 19)
#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_CERR_3 (3U << 23)
#define SOTG_PTD_DW3_CERR_2 (2U << 23) /* infinite NAKs */
#define SOTG_PTD_DW3_CERR_1 (1U << 23)
#define SOTG_PTD_DW3_XFER_COUNT 0x7FFF
#define SOTG_PTD_DW4 16
#define SOTG_PTD_DW5 20
@ -245,15 +249,24 @@
#define SOTG_HCINTERRUPT_DMAEOTINT (1 << 3)
#define SOTG_HCINTERRUPT_SOFITLINT (1 << 1)
#define SOTG_HCINTERRUPT_ENABLE 0x314
#define SOTG_ATL_PTD_DONE_PTD 0x150
#define SOTG_ATL_PTD_SKIP_PTD 0x154
#define SOTG_ATL_PTD_LAST_PTD 0x158
#define SOTG_INT_PTD_DONE_PTD 0x140
#define SOTG_INT_PTD_SKIP_PTD 0x144
#define SOTG_INT_PTD_LAST_PTD 0x148
#define SOTG_ISO_PTD_DONE_PTD 0x130
#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)
#define SOTG_ISO_IRQ_MASK_OR 0x318
#define SOTG_INT_IRQ_MASK_OR 0x31C
#define SOTG_ATL_IRQ_MASK_OR 0x320
#define SOTG_ISO_IRQ_MASK_AND 0x324
#define SOTG_INT_IRQ_MASK_AND 0x328
#define SOTG_ATL_IRQ_MASK_AND 0x32C
#endif /* _SAF1761_OTG_REG_H_ */