summaryrefslogtreecommitdiff
path: root/sys/src/9/zynq
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2015-02-14 03:00:31 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2015-02-14 03:00:31 +0100
commit995379e388e4cd202f683a00e99749c7f21a225d (patch)
tree046f2efc671554b5b6c5bfa9b8a38a95340a247f /sys/src/9/zynq
parent6b2d1f0186f2e38a3b0cd6a19b5980dccb045c3c (diff)
usbehci: initial support for usb on zynq, remove uncached.h
the following hooks have been added to the ehci Ctlr structore to handle cache coherency (on arm): void* (*tdalloc)(ulong,int,ulong); void* (*dmaalloc)(ulong); void (*dmafree)(void*); void (*dmaflush)(int,void*,ulong); tdalloc() is used to allocate descriptors and the periodic frame schedule array. on arm, this needs to return uncached memory. tdalloc()ed memory is never freed. dmaalloc()/dmafree() is used for io buffers. this can return cached memory when when hardware maintains cache coherency (pc) or dmaflush() is provided to flush/invalidate the cache (zynq), otherwise needs to return uncached memory. dmaflush() is used to flush/invalidate the cache. the first argument tells us if we need to flush (non zero) or invalidate (zero). uncached.h is gone now. this change makes the handling explicit.
Diffstat (limited to 'sys/src/9/zynq')
-rw-r--r--sys/src/9/zynq/mkfile2
-rw-r--r--sys/src/9/zynq/uncached.h27
-rw-r--r--sys/src/9/zynq/usbehci.h39
-rw-r--r--sys/src/9/zynq/usbehcizynq.c54
-rw-r--r--sys/src/9/zynq/zynq2
5 files changed, 81 insertions, 43 deletions
diff --git a/sys/src/9/zynq/mkfile b/sys/src/9/zynq/mkfile
index 079207241..5ba3628e9 100644
--- a/sys/src/9/zynq/mkfile
+++ b/sys/src/9/zynq/mkfile
@@ -86,5 +86,5 @@ install:V: $p$CONF
for(i in $EXTRACOPIES)
import $i / /n/$i && cp $p$CONF $p$CONF.gz /n/$i/$objtype/
-devusb.$O usbehci.$O usbehcizynq.$O: ../port/usb.h uncached.h
+devusb.$O usbehci.$O usbehcizynq.$O: ../port/usb.h
usbehci.$O usbehcizynq.$O: usbehci.h
diff --git a/sys/src/9/zynq/uncached.h b/sys/src/9/zynq/uncached.h
deleted file mode 100644
index 0a7b50883..000000000
--- a/sys/src/9/zynq/uncached.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#define free ucfree
-#define malloc myucalloc
-#define mallocz ucallocz
-#define smalloc myucalloc
-#define xspanalloc ucallocalign
-
-#define allocb ucallocb
-#define iallocb uciallocb
-#define freeb ucfreeb
-
-static void *
-ucallocz(uint n, int)
-{
- char *p = ucalloc(n);
-
- if (p)
- memset(p, 0, n);
- else
- panic("ucalloc: out of memory");
- return p;
-}
-
-static void *
-myucalloc(uint n)
-{
- return ucallocz(n, 1);
-}
diff --git a/sys/src/9/zynq/usbehci.h b/sys/src/9/zynq/usbehci.h
index 2c71d12bc..6b8b32fd0 100644
--- a/sys/src/9/zynq/usbehci.h
+++ b/sys/src/9/zynq/usbehci.h
@@ -84,16 +84,30 @@ typedef struct Qtree Qtree;
struct Eopio
{
- ulong cmd;
- ulong sts;
- ulong intr;
- ulong frno;
- ulong dummy1[2];
- ulong frbase;
- ulong link;
- ulong dummy2[9];
- ulong config;
- ulong portsc[1];
+/*140*/ ulong cmd;
+/*144*/ ulong sts;
+/*148*/ ulong intr;
+/*14c*/ ulong frno;
+
+/*150*/ ulong reserved1;
+
+/*154*/ ulong frbase;
+/*158*/ ulong link;
+
+/*15c*/ ulong _ttctrl;
+/*160*/ ulong _burstsize;
+/*164*/ ulong _txfilltuning;
+/*168*/ ulong _txttfilltuning;
+/*16c*/ ulong _ic_usb;
+/*170*/ ulong _ulpi_viewport;
+
+/*174*/ ulong reserved2;
+
+/*178*/ ulong _endptnak;
+/*17c*/ ulong _endptnaken;
+
+/*180*/ ulong config;
+/*184*/ ulong portsc[1];
};
struct Poll
@@ -113,6 +127,11 @@ struct Ctlr
void* capio; /* base address for debug info */
Eopio* opio; /* Operational i/o regs */
+ void* (*tdalloc)(ulong,int,ulong);
+ void* (*dmaalloc)(ulong);
+ void (*dmafree)(void*);
+ void (*dmaflush)(int,void*,ulong len);
+
int nframes; /* 1024, 512, or 256 frames in the list */
ulong* frames; /* periodic frame list (hw) */
Qh* qhs; /* async Qh circular list for bulk/ctl */
diff --git a/sys/src/9/zynq/usbehcizynq.c b/sys/src/9/zynq/usbehcizynq.c
index e233fb429..d5ec5b005 100644
--- a/sys/src/9/zynq/usbehcizynq.c
+++ b/sys/src/9/zynq/usbehcizynq.c
@@ -61,6 +61,47 @@ ehcireset(Ctlr *ctlr)
iunlock(ctlr);
}
+enum {
+ Cls = 64,
+};
+
+/* descriptors need to be allocated in uncached memory */
+static void*
+tdalloc(ulong size, int, ulong)
+{
+ return ucalloc(size);
+}
+
+static void*
+dmaalloc(ulong len)
+{
+ return mallocalign(ROUND(len, Cls), Cls, 0, 0);
+}
+static void
+dmafree(void *data)
+{
+ free(data);
+}
+
+static void
+dmaflush(int clean, void *data, ulong len)
+{
+ uintptr va, pa;
+
+ va = (uintptr)data & ~(Cls-1);
+ pa = PADDR(va);
+ len = ROUND(len, Cls);
+ if(clean){
+ /* flush cache before write */
+ cleandse((uchar*)va, (uchar*)va+len);
+ clean2pa(pa, pa+len);
+ } else {
+ /* invalidate cache before read */
+ invaldse((uchar*)va, (uchar*)va+len);
+ inval2pa(pa, pa+len);
+ }
+}
+
static int
reset(Hci *hp)
{
@@ -84,12 +125,17 @@ reset(Hci *hp)
ctlr->opio = (Eopio *) ((uchar *) ctlr->r + 0x140);
ctlr->capio = (void *) ctlr->base;
hp->nports = 1;
- ctlr->r[USBMODE] |= USBHOST;
-
+
+ ctlr->tdalloc = tdalloc;
+ ctlr->dmaalloc = dmaalloc;
+ ctlr->dmafree = dmafree;
+ ctlr->dmaflush = dmaflush;
+
ehcireset(ctlr);
+ ctlr->r[USBMODE] |= USBHOST;
+ ctlr->r[ULPI] = 1<<30 | 1<<29 | 0x0B << 16 | 3<<5;
ehcimeminit(ctlr);
ehcilinkage(hp);
- ctlr->r[ULPI] = 1<<30 | 1<<29 | 0x0B << 16 | 3<<5;
if(hp->interrupt != nil)
intrenable(hp->irq, hp->interrupt, hp, LEVEL, hp->type);
return 0;
@@ -98,6 +144,6 @@ reset(Hci *hp)
void
usbehcilink(void)
{
- ehcidebug = 2;
+// ehcidebug = 2;
addhcitype("ehci", reset);
}
diff --git a/sys/src/9/zynq/zynq b/sys/src/9/zynq/zynq
index 75d244ab7..7b67c902b 100644
--- a/sys/src/9/zynq/zynq
+++ b/sys/src/9/zynq/zynq
@@ -26,7 +26,7 @@ link
etherzynq
ethermedium
loopbackmedium
-# usbehci usbehcizynq
+ usbehci usbehcizynq
misc
uartzynq