zynq: fix usb by implementing delay() and give proper port speed in portstatus
This commit is contained in:
parent
07c7fa6716
commit
3cd7978a72
2 changed files with 37 additions and 3 deletions
|
@ -23,13 +23,19 @@ enum {
|
|||
uvlong timerhz;
|
||||
|
||||
void
|
||||
delay(int)
|
||||
microdelay(int n)
|
||||
{
|
||||
ulong now;
|
||||
|
||||
now = µs();
|
||||
while(µs() - now < n);
|
||||
}
|
||||
|
||||
void
|
||||
microdelay(int)
|
||||
delay(int n)
|
||||
{
|
||||
while(--n >= 0)
|
||||
microdelay(1000);
|
||||
}
|
||||
|
||||
uvlong
|
||||
|
|
|
@ -102,6 +102,29 @@ dmaflush(int clean, void *data, ulong len)
|
|||
}
|
||||
}
|
||||
|
||||
static int (*ehciportstatus)(Hci*,int);
|
||||
|
||||
static int
|
||||
portstatus(Hci *hp, int port)
|
||||
{
|
||||
Ctlr *ctlr;
|
||||
Eopio *opio;
|
||||
int r, sts;
|
||||
|
||||
ctlr = hp->aux;
|
||||
opio = ctlr->opio;
|
||||
r = (*ehciportstatus)(hp, port);
|
||||
if(r & HPpresent){
|
||||
sts = opio->portsc[port-1];
|
||||
r &= ~(HPhigh|HPslow);
|
||||
if(sts & (1<<9))
|
||||
r |= HPhigh;
|
||||
else if(sts & 1<<26)
|
||||
r |= HPslow;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
reset(Hci *hp)
|
||||
{
|
||||
|
@ -124,7 +147,7 @@ reset(Hci *hp)
|
|||
ctlr->r = vmap(ctlr->base, 0x1F0);
|
||||
ctlr->opio = (Eopio *) ((uchar *) ctlr->r + 0x140);
|
||||
ctlr->capio = (void *) ctlr->base;
|
||||
hp->nports = 1;
|
||||
hp->nports = 1;
|
||||
|
||||
ctlr->tdalloc = tdalloc;
|
||||
ctlr->dmaalloc = dmaalloc;
|
||||
|
@ -136,6 +159,11 @@ reset(Hci *hp)
|
|||
ctlr->r[ULPI] = 1<<30 | 1<<29 | 0x0B << 16 | 3<<5;
|
||||
ehcimeminit(ctlr);
|
||||
ehcilinkage(hp);
|
||||
|
||||
/* hook portstatus */
|
||||
ehciportstatus = hp->portstatus;
|
||||
hp->portstatus = portstatus;
|
||||
|
||||
if(hp->interrupt != nil)
|
||||
intrenable(hp->irq, hp->interrupt, hp, LEVEL, hp->type);
|
||||
return 0;
|
||||
|
|
Loading…
Reference in a new issue