Commit e5bb0284 authored by David Brownell's avatar David Brownell Committed by Tony Lindgren

MUSB: Update register access based on new HDRC core spec

Catch up to info from latest HDRC core spec ... some new registers
and fields, and constraints notably

 - not clearing TX fifo unless it's empty (that might explain some
   host side glitching).

 - not all POWER fields are writable
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
parent 044fe6d5
...@@ -387,9 +387,10 @@ stall: ...@@ -387,9 +387,10 @@ stall:
if (is_in) { if (is_in) {
csr = musb_readw(regs, csr = musb_readw(regs,
MGC_O_HDRC_TXCSR); MGC_O_HDRC_TXCSR);
if (csr & MGC_M_TXCSR_FIFONOTEMPTY)
csr |= MGC_M_TXCSR_FLUSHFIFO;
csr |= MGC_M_TXCSR_P_SENDSTALL csr |= MGC_M_TXCSR_P_SENDSTALL
| MGC_M_TXCSR_CLRDATATOG | MGC_M_TXCSR_CLRDATATOG
| MGC_M_TXCSR_FLUSHFIFO
| MGC_M_TXCSR_P_WZC_BITS; | MGC_M_TXCSR_P_WZC_BITS;
musb_writew(regs, MGC_O_HDRC_TXCSR, musb_writew(regs, MGC_O_HDRC_TXCSR,
csr); csr);
......
...@@ -297,6 +297,7 @@ static void txstate(struct musb *pThis, struct musb_request *req) ...@@ -297,6 +297,7 @@ static void txstate(struct musb *pThis, struct musb_request *req)
pRequest->dma, request_size); pRequest->dma, request_size);
if (use_dma) { if (use_dma) {
if (pEnd->dma->bDesiredMode == 0) { if (pEnd->dma->bDesiredMode == 0) {
/* ASSERT: DMAENAB is clear */
wCsrVal &= ~(MGC_M_TXCSR_AUTOSET | wCsrVal &= ~(MGC_M_TXCSR_AUTOSET |
MGC_M_TXCSR_DMAMODE); MGC_M_TXCSR_DMAMODE);
wCsrVal |= (MGC_M_TXCSR_DMAENAB | wCsrVal |= (MGC_M_TXCSR_DMAENAB |
...@@ -347,6 +348,7 @@ static void txstate(struct musb *pThis, struct musb_request *req) ...@@ -347,6 +348,7 @@ static void txstate(struct musb *pThis, struct musb_request *req)
if (!use_dma) { if (!use_dma) {
c->channel_release(pEnd->dma); c->channel_release(pEnd->dma);
pEnd->dma = NULL; pEnd->dma = NULL;
/* ASSERT: DMAENAB clear */
wCsrVal &= ~(MGC_M_TXCSR_DMAMODE | MGC_M_TXCSR_MODE); wCsrVal &= ~(MGC_M_TXCSR_DMAMODE | MGC_M_TXCSR_MODE);
/* invariant: prequest->buf is non-null */ /* invariant: prequest->buf is non-null */
} }
...@@ -839,6 +841,8 @@ static int musb_gadget_enable(struct usb_ep *ep, ...@@ -839,6 +841,8 @@ static int musb_gadget_enable(struct usb_ep *ep,
{ {
unsigned long flags; unsigned long flags;
struct musb_ep *pEnd; struct musb_ep *pEnd;
struct musb_hw_ep *hw_ep;
void __iomem *regs;
struct musb *pThis; struct musb *pThis;
void __iomem *pBase; void __iomem *pBase;
u8 bEnd; u8 bEnd;
...@@ -850,6 +854,8 @@ static int musb_gadget_enable(struct usb_ep *ep, ...@@ -850,6 +854,8 @@ static int musb_gadget_enable(struct usb_ep *ep,
return -EINVAL; return -EINVAL;
pEnd = to_musb_ep(ep); pEnd = to_musb_ep(ep);
hw_ep = pEnd->hw_ep;
regs = hw_ep->regs;
pThis = pEnd->pThis; pThis = pEnd->pThis;
pBase = pThis->pRegs; pBase = pThis->pRegs;
bEnd = pEnd->bEndNumber; bEnd = pEnd->bEndNumber;
...@@ -879,11 +885,11 @@ static int musb_gadget_enable(struct usb_ep *ep, ...@@ -879,11 +885,11 @@ static int musb_gadget_enable(struct usb_ep *ep,
if (desc->bEndpointAddress & USB_DIR_IN) { if (desc->bEndpointAddress & USB_DIR_IN) {
u16 wIntrTxE = musb_readw(pBase, MGC_O_HDRC_INTRTXE); u16 wIntrTxE = musb_readw(pBase, MGC_O_HDRC_INTRTXE);
if (pEnd->hw_ep->bIsSharedFifo) if (hw_ep->bIsSharedFifo)
pEnd->is_in = 1; pEnd->is_in = 1;
if (!pEnd->is_in) if (!pEnd->is_in)
goto fail; goto fail;
if (tmp > pEnd->hw_ep->wMaxPacketSizeTx) if (tmp > hw_ep->wMaxPacketSizeTx)
goto fail; goto fail;
wIntrTxE |= (1 << bEnd); wIntrTxE |= (1 << bEnd);
...@@ -892,25 +898,28 @@ static int musb_gadget_enable(struct usb_ep *ep, ...@@ -892,25 +898,28 @@ static int musb_gadget_enable(struct usb_ep *ep,
/* REVISIT if can_bulk_split(), use by updating "tmp"; /* REVISIT if can_bulk_split(), use by updating "tmp";
* likewise high bandwidth periodic tx * likewise high bandwidth periodic tx
*/ */
MGC_WriteCsr16(pBase, MGC_O_HDRC_TXMAXP, bEnd, tmp); musb_writew(regs, MGC_O_HDRC_TXMAXP, tmp);
csr = MGC_M_TXCSR_MODE | MGC_M_TXCSR_CLRDATATOG csr = MGC_M_TXCSR_MODE | MGC_M_TXCSR_CLRDATATOG;
| MGC_M_TXCSR_FLUSHFIFO; if (musb_readw(regs, MGC_O_HDRC_TXCSR)
& MGC_M_TXCSR_FIFONOTEMPTY)
csr |= MGC_M_TXCSR_FLUSHFIFO;
if (pEnd->type == USB_ENDPOINT_XFER_ISOC) if (pEnd->type == USB_ENDPOINT_XFER_ISOC)
csr |= MGC_M_TXCSR_P_ISO; csr |= MGC_M_TXCSR_P_ISO;
/* set twice in case of double buffering */ /* set twice in case of double buffering */
MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, csr); musb_writew(regs, MGC_O_HDRC_TXCSR, csr);
MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, csr); /* REVISIT may be inappropriate w/o FIFONOTEMPTY ... */
musb_writew(regs, MGC_O_HDRC_TXCSR, csr);
} else { } else {
u16 wIntrRxE = musb_readw(pBase, MGC_O_HDRC_INTRRXE); u16 wIntrRxE = musb_readw(pBase, MGC_O_HDRC_INTRRXE);
if (pEnd->hw_ep->bIsSharedFifo) if (hw_ep->bIsSharedFifo)
pEnd->is_in = 0; pEnd->is_in = 0;
if (pEnd->is_in) if (pEnd->is_in)
goto fail; goto fail;
if (tmp > pEnd->hw_ep->wMaxPacketSizeRx) if (tmp > hw_ep->wMaxPacketSizeRx)
goto fail; goto fail;
wIntrRxE |= (1 << bEnd); wIntrRxE |= (1 << bEnd);
...@@ -922,7 +931,7 @@ static int musb_gadget_enable(struct usb_ep *ep, ...@@ -922,7 +931,7 @@ static int musb_gadget_enable(struct usb_ep *ep,
MGC_WriteCsr16(pBase, MGC_O_HDRC_RXMAXP, bEnd, tmp); MGC_WriteCsr16(pBase, MGC_O_HDRC_RXMAXP, bEnd, tmp);
/* force shared fifo to OUT-only mode */ /* force shared fifo to OUT-only mode */
if (pEnd->hw_ep->bIsSharedFifo) { if (hw_ep->bIsSharedFifo) {
csr = musb_readw(pBase, MGC_O_HDRC_TXCSR); csr = musb_readw(pBase, MGC_O_HDRC_TXCSR);
csr &= ~(MGC_M_TXCSR_MODE | MGC_M_TXCSR_TXPKTRDY); csr &= ~(MGC_M_TXCSR_MODE | MGC_M_TXCSR_TXPKTRDY);
MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, csr); MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, csr);
...@@ -945,7 +954,7 @@ static int musb_gadget_enable(struct usb_ep *ep, ...@@ -945,7 +954,7 @@ static int musb_gadget_enable(struct usb_ep *ep,
if (is_dma_capable() && pThis->pDmaController) { if (is_dma_capable() && pThis->pDmaController) {
struct dma_controller *c = pThis->pDmaController; struct dma_controller *c = pThis->pDmaController;
pEnd->dma = c->channel_alloc(c, pEnd->hw_ep, pEnd->dma = c->channel_alloc(c, hw_ep,
(desc->bEndpointAddress & USB_DIR_IN)); (desc->bEndpointAddress & USB_DIR_IN));
} else } else
pEnd->dma = NULL; pEnd->dma = NULL;
...@@ -1292,9 +1301,10 @@ int musb_gadget_set_halt(struct usb_ep *ep, int value) ...@@ -1292,9 +1301,10 @@ int musb_gadget_set_halt(struct usb_ep *ep, int value)
DBG(2, "%s: %s stall\n", ep->name, value ? "set" : "clear"); DBG(2, "%s: %s stall\n", ep->name, value ? "set" : "clear");
if (pEnd->is_in) { if (pEnd->is_in) {
wCsr = MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd); wCsr = MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd);
if (wCsr & MGC_M_TXCSR_FIFONOTEMPTY)
wCsr |= MGC_M_TXCSR_FLUSHFIFO;
wCsr |= MGC_M_TXCSR_P_WZC_BITS wCsr |= MGC_M_TXCSR_P_WZC_BITS
| MGC_M_TXCSR_CLRDATATOG | MGC_M_TXCSR_CLRDATATOG;
| MGC_M_TXCSR_FLUSHFIFO;
if (value) if (value)
wCsr |= MGC_M_TXCSR_P_SENDSTALL; wCsr |= MGC_M_TXCSR_P_SENDSTALL;
else else
...@@ -1371,9 +1381,12 @@ static void musb_gadget_fifo_flush(struct usb_ep *ep) ...@@ -1371,9 +1381,12 @@ static void musb_gadget_fifo_flush(struct usb_ep *ep)
if (musb_ep->is_in) { if (musb_ep->is_in) {
wCsr = MGC_ReadCsr16(mbase, MGC_O_HDRC_TXCSR, nEnd); wCsr = MGC_ReadCsr16(mbase, MGC_O_HDRC_TXCSR, nEnd);
if (wCsr & MGC_M_TXCSR_FIFONOTEMPTY) {
wCsr |= MGC_M_TXCSR_FLUSHFIFO | MGC_M_TXCSR_P_WZC_BITS; wCsr |= MGC_M_TXCSR_FLUSHFIFO | MGC_M_TXCSR_P_WZC_BITS;
MGC_WriteCsr16(mbase, MGC_O_HDRC_TXCSR, nEnd, wCsr); MGC_WriteCsr16(mbase, MGC_O_HDRC_TXCSR, nEnd, wCsr);
/* REVISIT may be inappropriate w/o FIFONOTEMPTY ... */
MGC_WriteCsr16(mbase, MGC_O_HDRC_TXCSR, nEnd, wCsr); MGC_WriteCsr16(mbase, MGC_O_HDRC_TXCSR, nEnd, wCsr);
}
} else { } else {
wCsr = MGC_ReadCsr16(mbase, MGC_O_HDRC_RXCSR, nEnd); wCsr = MGC_ReadCsr16(mbase, MGC_O_HDRC_RXCSR, nEnd);
wCsr |= MGC_M_RXCSR_FLUSHFIFO | MGC_M_RXCSR_P_WZC_BITS; wCsr |= MGC_M_RXCSR_FLUSHFIFO | MGC_M_RXCSR_P_WZC_BITS;
...@@ -1413,17 +1426,21 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget) ...@@ -1413,17 +1426,21 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget)
{ {
struct musb *musb = gadget_to_musb(gadget); struct musb *musb = gadget_to_musb(gadget);
unsigned long flags; unsigned long flags;
int status = 0; int status = -EINVAL;
u8 power; u8 power;
spin_lock_irqsave(&musb->Lock, flags); spin_lock_irqsave(&musb->Lock, flags);
/* fail if we're not suspended */
power = musb_readb(musb->pRegs, MGC_O_HDRC_POWER);
if (!(power & MGC_M_POWER_SUSPENDM))
goto done;
switch (musb->xceiv.state) { switch (musb->xceiv.state) {
case OTG_STATE_B_PERIPHERAL: case OTG_STATE_B_PERIPHERAL:
/* FIXME if not suspended, fail */
if (musb->bMayWakeup) if (musb->bMayWakeup)
break; break;
goto fail; goto done;
case OTG_STATE_B_IDLE: case OTG_STATE_B_IDLE:
/* REVISIT we might be able to do SRP even without OTG, /* REVISIT we might be able to do SRP even without OTG,
* though Linux doesn't yet expose that capability * though Linux doesn't yet expose that capability
...@@ -1434,12 +1451,10 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget) ...@@ -1434,12 +1451,10 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget)
} }
/* FALLTHROUGH */ /* FALLTHROUGH */
default: default:
fail:
status = -EINVAL;
goto done; goto done;
} }
power = musb_readb(musb->pRegs, MGC_O_HDRC_POWER); status = 0;
power |= MGC_M_POWER_RESUME; power |= MGC_M_POWER_RESUME;
musb_writeb(musb->pRegs, MGC_O_HDRC_POWER, power); musb_writeb(musb->pRegs, MGC_O_HDRC_POWER, power);
......
...@@ -717,7 +717,11 @@ static void musb_ep_program(struct musb *pThis, u8 bEnd, ...@@ -717,7 +717,11 @@ static void musb_ep_program(struct musb *pThis, u8 bEnd,
if (bEnd) { if (bEnd) {
u16 csr = wCsr; u16 csr = wCsr;
/* ASSERT: TXCSR_DMAENAB was already cleared */
/* flush all old state, set default */ /* flush all old state, set default */
if (csr & MGC_M_TXCSR_FIFONOTEMPTY)
csr |= MGC_M_TXCSR_FLUSHFIFO;
csr &= ~(MGC_M_TXCSR_H_NAKTIMEOUT csr &= ~(MGC_M_TXCSR_H_NAKTIMEOUT
| MGC_M_TXCSR_DMAMODE | MGC_M_TXCSR_DMAMODE
| MGC_M_TXCSR_FRCDATATOG | MGC_M_TXCSR_FRCDATATOG
...@@ -727,8 +731,7 @@ static void musb_ep_program(struct musb *pThis, u8 bEnd, ...@@ -727,8 +731,7 @@ static void musb_ep_program(struct musb *pThis, u8 bEnd,
| MGC_M_TXCSR_FIFONOTEMPTY | MGC_M_TXCSR_FIFONOTEMPTY
| MGC_M_TXCSR_TXPKTRDY | MGC_M_TXCSR_TXPKTRDY
); );
csr |= MGC_M_TXCSR_FLUSHFIFO csr |= MGC_M_TXCSR_MODE;
| MGC_M_TXCSR_MODE;
if (qh->type == USB_ENDPOINT_XFER_ISOC) if (qh->type == USB_ENDPOINT_XFER_ISOC)
csr |= MGC_M_TXCSR_ISO; csr |= MGC_M_TXCSR_ISO;
...@@ -742,6 +745,7 @@ static void musb_ep_program(struct musb *pThis, u8 bEnd, ...@@ -742,6 +745,7 @@ static void musb_ep_program(struct musb *pThis, u8 bEnd,
/* twice in case of double packet buffering */ /* twice in case of double packet buffering */
MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd,
csr); csr);
/* REVISIT may need to clear FLUSHFIFO ... */
MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd,
csr); csr);
wCsr = MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR, wCsr = MGC_ReadCsr16(pBase, MGC_O_HDRC_TXCSR,
...@@ -765,6 +769,7 @@ static void musb_ep_program(struct musb *pThis, u8 bEnd, ...@@ -765,6 +769,7 @@ static void musb_ep_program(struct musb *pThis, u8 bEnd,
musb_writeb(pBase, musb_writeb(pBase,
MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBPORT), MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBPORT),
qh->h_port_reg); qh->h_port_reg);
/* FIXME if !bEnd, do the same for RX ... */
} else } else
musb_writeb(pBase, MGC_O_HDRC_FADDR, qh->addr_reg); musb_writeb(pBase, MGC_O_HDRC_FADDR, qh->addr_reg);
...@@ -884,6 +889,8 @@ static void musb_ep_program(struct musb *pThis, u8 bEnd, ...@@ -884,6 +889,8 @@ static void musb_ep_program(struct musb *pThis, u8 bEnd,
} }
#endif #endif
if (wLoadCount) { if (wLoadCount) {
/* ASSERT: TXCSR_DMAENAB was already cleared */
/* PIO to load FIFO */ /* PIO to load FIFO */
qh->segsize = wLoadCount; qh->segsize = wLoadCount;
musb_write_fifo(pEnd, wLoadCount, pBuffer); musb_write_fifo(pEnd, wLoadCount, pBuffer);
...@@ -1223,13 +1230,15 @@ void musb_host_tx(struct musb *pThis, u8 bEnd) ...@@ -1223,13 +1230,15 @@ void musb_host_tx(struct musb *pThis, u8 bEnd)
/* check for errors */ /* check for errors */
if (wTxCsrVal & MGC_M_TXCSR_H_RXSTALL) { if (wTxCsrVal & MGC_M_TXCSR_H_RXSTALL) {
/* dma was disabled, fifo flushed */
DBG(3, "TX end %d stall\n", bEnd); DBG(3, "TX end %d stall\n", bEnd);
/* stall; record URB status */ /* stall; record URB status */
status = -EPIPE; status = -EPIPE;
} else if (wTxCsrVal & MGC_M_TXCSR_H_ERROR) { } else if (wTxCsrVal & MGC_M_TXCSR_H_ERROR) {
DBG(3, "TX data error on ep=%d\n", bEnd); /* (NON-ISO) dma was disabled, fifo flushed */
DBG(3, "TX 3strikes on ep=%d\n", bEnd);
status = -ETIMEDOUT; status = -ETIMEDOUT;
...@@ -1260,6 +1269,8 @@ void musb_host_tx(struct musb *pThis, u8 bEnd) ...@@ -1260,6 +1269,8 @@ void musb_host_tx(struct musb *pThis, u8 bEnd)
* usb core; the dma engine should already be stopped. * usb core; the dma engine should already be stopped.
*/ */
// SCRUB (TX) // SCRUB (TX)
if (wTxCsrVal & MGC_M_TXCSR_FIFONOTEMPTY)
wTxCsrVal |= MGC_M_TXCSR_FLUSHFIFO;
wTxCsrVal &= ~(MGC_M_TXCSR_FIFONOTEMPTY wTxCsrVal &= ~(MGC_M_TXCSR_FIFONOTEMPTY
| MGC_M_TXCSR_AUTOSET | MGC_M_TXCSR_AUTOSET
| MGC_M_TXCSR_DMAENAB | MGC_M_TXCSR_DMAENAB
...@@ -1267,10 +1278,10 @@ void musb_host_tx(struct musb *pThis, u8 bEnd) ...@@ -1267,10 +1278,10 @@ void musb_host_tx(struct musb *pThis, u8 bEnd)
| MGC_M_TXCSR_H_RXSTALL | MGC_M_TXCSR_H_RXSTALL
| MGC_M_TXCSR_H_NAKTIMEOUT | MGC_M_TXCSR_H_NAKTIMEOUT
); );
wTxCsrVal |= MGC_M_TXCSR_FLUSHFIFO;
MGC_SelectEnd(pBase, bEnd); MGC_SelectEnd(pBase, bEnd);
MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wTxCsrVal); MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wTxCsrVal);
/* REVISIT may need to clear FLUSHFIFO ... */
MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wTxCsrVal); MGC_WriteCsr16(pBase, MGC_O_HDRC_TXCSR, bEnd, wTxCsrVal);
MGC_WriteCsr8(pBase, MGC_O_HDRC_TXINTERVAL, bEnd, 0); MGC_WriteCsr8(pBase, MGC_O_HDRC_TXINTERVAL, bEnd, 0);
...@@ -1977,6 +1988,8 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh, int is_in) ...@@ -1977,6 +1988,8 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh, int is_in)
} else { } else {
// SCRUB (TX) // SCRUB (TX)
csr = MGC_ReadCsr16(regs, MGC_O_HDRC_TXCSR, hw_end); csr = MGC_ReadCsr16(regs, MGC_O_HDRC_TXCSR, hw_end);
if (csr & MGC_M_TXCSR_FIFONOTEMPTY)
csr |= MGC_M_TXCSR_FLUSHFIFO;
csr &= ~( MGC_M_TXCSR_AUTOSET csr &= ~( MGC_M_TXCSR_AUTOSET
| MGC_M_TXCSR_DMAENAB | MGC_M_TXCSR_DMAENAB
| MGC_M_TXCSR_H_RXSTALL | MGC_M_TXCSR_H_RXSTALL
...@@ -1984,8 +1997,8 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh, int is_in) ...@@ -1984,8 +1997,8 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh, int is_in)
| MGC_M_TXCSR_H_ERROR | MGC_M_TXCSR_H_ERROR
| MGC_M_TXCSR_FIFONOTEMPTY | MGC_M_TXCSR_FIFONOTEMPTY
); );
csr |= MGC_M_TXCSR_FLUSHFIFO;
MGC_WriteCsr16(regs, MGC_O_HDRC_TXCSR, 0, csr); MGC_WriteCsr16(regs, MGC_O_HDRC_TXCSR, 0, csr);
/* REVISIT may need to clear FLUSHFIFO ... */
MGC_WriteCsr16(regs, MGC_O_HDRC_TXCSR, 0, csr); MGC_WriteCsr16(regs, MGC_O_HDRC_TXCSR, 0, csr);
/* flush cpu writebuffer */ /* flush cpu writebuffer */
csr = MGC_ReadCsr16(regs, MGC_O_HDRC_TXCSR, hw_end); csr = MGC_ReadCsr16(regs, MGC_O_HDRC_TXCSR, hw_end);
......
...@@ -71,8 +71,6 @@ ...@@ -71,8 +71,6 @@
/* Additional Control Registers */ /* Additional Control Registers */
#define MGC_O_HDRC_DEVCTL 0x60 /* 8 bit */ #define MGC_O_HDRC_DEVCTL 0x60 /* 8 bit */
// vctrl/vstatus: optional vendor utmi+phy register at 0x68
#define MGC_O_HDRC_HWVERS 0x6C /* 8 bit */
/* These are always controlled through the INDEX register */ /* These are always controlled through the INDEX register */
#define MGC_O_HDRC_TXFIFOSZ 0x62 /* 8-bit (see masks) */ #define MGC_O_HDRC_TXFIFOSZ 0x62 /* 8-bit (see masks) */
...@@ -80,6 +78,17 @@ ...@@ -80,6 +78,17 @@
#define MGC_O_HDRC_TXFIFOADD 0x64 /* 16-bit offset shifted right 3 */ #define MGC_O_HDRC_TXFIFOADD 0x64 /* 16-bit offset shifted right 3 */
#define MGC_O_HDRC_RXFIFOADD 0x66 /* 16-bit offset shifted right 3 */ #define MGC_O_HDRC_RXFIFOADD 0x66 /* 16-bit offset shifted right 3 */
// vctrl/vstatus: optional vendor utmi+phy register at 0x68
#define MGC_O_HDRC_HWVERS 0x6C /* 8 bit */
#define MGC_O_HDRC_EPINFO 0x78 /* 8 bit */
#define MGC_O_HDRC_RAMINFO 0x79 /* 8 bit */
#define MGC_O_HDRC_LINKINFO 0x7a /* 8 bit */
#define MGC_O_HDRC_VPLEN 0x7b /* 8 bit */
#define MGC_O_HDRC_HS_EOF1 0x7c /* 8 bit */
#define MGC_O_HDRC_FS_EOF1 0x7d /* 8 bit */
#define MGC_O_HDRC_LS_EOF1 0x7e /* 8 bit */
/* offsets to endpoint registers */ /* offsets to endpoint registers */
#define MGC_O_HDRC_TXMAXP 0x00 #define MGC_O_HDRC_TXMAXP 0x00
#define MGC_O_HDRC_TXCSR 0x02 #define MGC_O_HDRC_TXCSR 0x02
...@@ -112,7 +121,7 @@ ...@@ -112,7 +121,7 @@
#include "tusb6010.h" /* needed "only" for TUSB_EP0_CONF */ #include "tusb6010.h" /* needed "only" for TUSB_EP0_CONF */
#endif #endif
/* "bus control" registers */ /* "bus control"/target registers, for host side multipoint (external hubs) */
#define MGC_O_HDRC_TXFUNCADDR 0x00 #define MGC_O_HDRC_TXFUNCADDR 0x00
#define MGC_O_HDRC_TXHUBADDR 0x02 #define MGC_O_HDRC_TXHUBADDR 0x02
#define MGC_O_HDRC_TXHUBPORT 0x03 #define MGC_O_HDRC_TXHUBPORT 0x03
...@@ -149,7 +158,6 @@ ...@@ -149,7 +158,6 @@
#define MGC_M_INTR_DISCONNECT 0x20 #define MGC_M_INTR_DISCONNECT 0x20
#define MGC_M_INTR_SESSREQ 0x40 #define MGC_M_INTR_SESSREQ 0x40
#define MGC_M_INTR_VBUSERROR 0x80 /* FOR SESSION END */ #define MGC_M_INTR_VBUSERROR 0x80 /* FOR SESSION END */
#define MGC_M_INTR_EP0 0x01 /* FOR EP0 INTERRUPT */
/* DEVCTL */ /* DEVCTL */
#define MGC_M_DEVCTL_BDEVICE 0x80 #define MGC_M_DEVCTL_BDEVICE 0x80
...@@ -191,6 +199,7 @@ ...@@ -191,6 +199,7 @@
#define MGC_M_CSR0_P_SENTSTALL 0x0004 #define MGC_M_CSR0_P_SENTSTALL 0x0004
/* CSR0 in Host mode */ /* CSR0 in Host mode */
#define MGC_M_CSR0_H_DIS_PING 0x0800
#define MGC_M_CSR0_H_WR_DATATOGGLE 0x0400 /* set to allow setting: */ #define MGC_M_CSR0_H_WR_DATATOGGLE 0x0400 /* set to allow setting: */
#define MGC_M_CSR0_H_DATATOGGLE 0x0200 /* data toggle control */ #define MGC_M_CSR0_H_DATATOGGLE 0x0200 /* data toggle control */
#define MGC_M_CSR0_H_NAKTIMEOUT 0x0080 #define MGC_M_CSR0_H_NAKTIMEOUT 0x0080
...@@ -214,9 +223,9 @@ ...@@ -214,9 +223,9 @@
#define MGC_TYPE_SPEED_HIGH 1 #define MGC_TYPE_SPEED_HIGH 1
#define MGC_TYPE_SPEED_FULL 2 #define MGC_TYPE_SPEED_FULL 2
#define MGC_TYPE_SPEED_LOW 3 #define MGC_TYPE_SPEED_LOW 3
#define MGC_M_TYPE_PROTO 0x30 #define MGC_M_TYPE_PROTO 0x30 /* implicitly zero for ep0 */
#define MGC_S_TYPE_PROTO 4 #define MGC_S_TYPE_PROTO 4
#define MGC_M_TYPE_REMOTE_END 0xf #define MGC_M_TYPE_REMOTE_END 0xf /* implicitly zero for ep0 */
/* CONFIGDATA */ /* CONFIGDATA */
...@@ -271,6 +280,7 @@ ...@@ -271,6 +280,7 @@
#define MGC_M_RXCSR_AUTOCLEAR 0x8000 #define MGC_M_RXCSR_AUTOCLEAR 0x8000
#define MGC_M_RXCSR_DMAENAB 0x2000 #define MGC_M_RXCSR_DMAENAB 0x2000
#define MGC_M_RXCSR_DISNYET 0x1000 #define MGC_M_RXCSR_DISNYET 0x1000
#define MGC_M_RXCSR_PID_ERR 0x1000
#define MGC_M_RXCSR_DMAMODE 0x0800 #define MGC_M_RXCSR_DMAMODE 0x0800
#define MGC_M_RXCSR_INCOMPRX 0x0100 #define MGC_M_RXCSR_INCOMPRX 0x0100
#define MGC_M_RXCSR_CLRDATATOG 0x0080 #define MGC_M_RXCSR_CLRDATATOG 0x0080
......
...@@ -387,7 +387,10 @@ static irqreturn_t musb_stage0_irq(struct musb * pThis, u8 bIntrUSB, ...@@ -387,7 +387,10 @@ static irqreturn_t musb_stage0_irq(struct musb * pThis, u8 bIntrUSB,
if (devctl & MGC_M_DEVCTL_HM) { if (devctl & MGC_M_DEVCTL_HM) {
#ifdef CONFIG_USB_MUSB_HDRC_HCD #ifdef CONFIG_USB_MUSB_HDRC_HCD
/* REVISIT: this is where SRP kicks in, yes? */ /* REVISIT: this is where SRP kicks in, yes?
* host responsibility should be to CLEAR the
* resume signaling after 50 msec ...
*/
MUSB_HST_MODE(pThis); /* unnecessary */ MUSB_HST_MODE(pThis); /* unnecessary */
power &= ~MGC_M_POWER_SUSPENDM; power &= ~MGC_M_POWER_SUSPENDM;
musb_writeb(pBase, MGC_O_HDRC_POWER, musb_writeb(pBase, MGC_O_HDRC_POWER,
......
...@@ -60,7 +60,6 @@ static void musb_port_suspend(struct musb *musb, u8 bSuspend) ...@@ -60,7 +60,6 @@ static void musb_port_suspend(struct musb *musb, u8 bSuspend)
musb->port1_status |= USB_PORT_STAT_SUSPEND; musb->port1_status |= USB_PORT_STAT_SUSPEND;
} else if (power & MGC_M_POWER_SUSPENDM) { } else if (power & MGC_M_POWER_SUSPENDM) {
DBG(3, "Root port resumed\n"); DBG(3, "Root port resumed\n");
power &= ~(MGC_M_POWER_SUSPENDM | MGC_M_POWER_RESUME);
musb_writeb(pBase, MGC_O_HDRC_POWER, musb_writeb(pBase, MGC_O_HDRC_POWER,
power | MGC_M_POWER_RESUME); power | MGC_M_POWER_RESUME);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment