bcm, bcm64: add dmaflush() function and make virtio size and virtual address configurable in Soc.virtio and Soc.iosize
This commit is contained in:
parent
4983adfa2c
commit
5a0c2e2d17
10 changed files with 68 additions and 21 deletions
|
@ -15,8 +15,10 @@
|
||||||
|
|
||||||
Soc soc = {
|
Soc soc = {
|
||||||
.dramsize = 512*MiB,
|
.dramsize = 512*MiB,
|
||||||
.physio = 0x20000000,
|
|
||||||
.busdram = 0x40000000,
|
.busdram = 0x40000000,
|
||||||
|
.iosize = 16*MiB,
|
||||||
|
.virtio = VIRTIO,
|
||||||
|
.physio = 0x20000000,
|
||||||
.busio = 0x7E000000,
|
.busio = 0x7E000000,
|
||||||
.armlocal = 0,
|
.armlocal = 0,
|
||||||
.l1ptedramattrs = Cached | Buffered,
|
.l1ptedramattrs = Cached | Buffered,
|
||||||
|
|
|
@ -20,8 +20,10 @@ typedef struct Mboxes Mboxes;
|
||||||
|
|
||||||
Soc soc = {
|
Soc soc = {
|
||||||
.dramsize = 0x3F000000, /* was 1024*MiB, but overlaps with physio */
|
.dramsize = 0x3F000000, /* was 1024*MiB, but overlaps with physio */
|
||||||
.physio = 0x3F000000,
|
|
||||||
.busdram = 0xC0000000,
|
.busdram = 0xC0000000,
|
||||||
|
.iosize = 16*MiB,
|
||||||
|
.virtio = VIRTIO,
|
||||||
|
.physio = 0x3F000000,
|
||||||
.busio = 0x7E000000,
|
.busio = 0x7E000000,
|
||||||
.armlocal = 0x40000000,
|
.armlocal = 0x40000000,
|
||||||
.l1ptedramattrs = Cached | Buffered | L1wralloc | L1sharable,
|
.l1ptedramattrs = Cached | Buffered | L1wralloc | L1sharable,
|
||||||
|
|
|
@ -281,17 +281,17 @@ struct DevConf
|
||||||
|
|
||||||
struct Soc { /* SoC dependent configuration */
|
struct Soc { /* SoC dependent configuration */
|
||||||
ulong dramsize;
|
ulong dramsize;
|
||||||
uintptr physio;
|
ulong iosize;
|
||||||
uintptr busdram;
|
uintptr busdram;
|
||||||
uintptr busio;
|
uintptr busio;
|
||||||
|
uintptr physio;
|
||||||
|
uintptr virtio;
|
||||||
uintptr armlocal;
|
uintptr armlocal;
|
||||||
u32int l1ptedramattrs;
|
u32int l1ptedramattrs;
|
||||||
u32int l2ptedramattrs;
|
u32int l2ptedramattrs;
|
||||||
};
|
};
|
||||||
extern Soc soc;
|
extern Soc soc;
|
||||||
|
|
||||||
#define BUSUNKNOWN -1
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GPIO
|
* GPIO
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -82,6 +82,8 @@ struct Ctlr {
|
||||||
Cb *cb;
|
Cb *cb;
|
||||||
Rendez r;
|
Rendez r;
|
||||||
int dmadone;
|
int dmadone;
|
||||||
|
void *flush;
|
||||||
|
int len;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Cb {
|
struct Cb {
|
||||||
|
@ -108,7 +110,7 @@ dmaaddr(void *va)
|
||||||
static uintptr
|
static uintptr
|
||||||
dmaioaddr(void *va)
|
dmaioaddr(void *va)
|
||||||
{
|
{
|
||||||
return soc.busio | ((uintptr)va - VIRTIO);
|
return soc.busio | ((uintptr)va - soc.virtio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -164,26 +166,28 @@ dmastart(int chan, int dev, int dir, void *src, void *dst, int len)
|
||||||
ctlr->regs[Cs] = Reset;
|
ctlr->regs[Cs] = Reset;
|
||||||
while(ctlr->regs[Cs] & Reset)
|
while(ctlr->regs[Cs] & Reset)
|
||||||
;
|
;
|
||||||
intrenable(IRQDMA(chan), dmainterrupt, ctlr, 0, "dma");
|
intrenable(IRQDMA(chan), dmainterrupt, ctlr, BUSUNKNOWN, "dma");
|
||||||
}
|
}
|
||||||
|
ctlr->len = len;
|
||||||
cb = ctlr->cb;
|
cb = ctlr->cb;
|
||||||
ti = 0;
|
ti = 0;
|
||||||
switch(dir){
|
switch(dir){
|
||||||
case DmaD2M:
|
case DmaD2M:
|
||||||
cachedwbinvse(dst, len);
|
ctlr->flush = dst;
|
||||||
ti = Srcdreq | Destinc;
|
ti = Srcdreq | Destinc;
|
||||||
cb->sourcead = dmaioaddr(src);
|
cb->sourcead = dmaioaddr(src);
|
||||||
cb->destad = dmaaddr(dst);
|
cb->destad = dmaaddr(dst);
|
||||||
break;
|
break;
|
||||||
case DmaM2D:
|
case DmaM2D:
|
||||||
cachedwbse(src, len);
|
ctlr->flush = nil;
|
||||||
|
dmaflush(1, src, len);
|
||||||
ti = Destdreq | Srcinc;
|
ti = Destdreq | Srcinc;
|
||||||
cb->sourcead = dmaaddr(src);
|
cb->sourcead = dmaaddr(src);
|
||||||
cb->destad = dmaioaddr(dst);
|
cb->destad = dmaioaddr(dst);
|
||||||
break;
|
break;
|
||||||
case DmaM2M:
|
case DmaM2M:
|
||||||
cachedwbse(src, len);
|
ctlr->flush = dst;
|
||||||
cachedwbinvse(dst, len);
|
dmaflush(1, src, len);
|
||||||
ti = Srcinc | Destinc;
|
ti = Srcinc | Destinc;
|
||||||
cb->sourcead = dmaaddr(src);
|
cb->sourcead = dmaaddr(src);
|
||||||
cb->destad = dmaaddr(dst);
|
cb->destad = dmaaddr(dst);
|
||||||
|
@ -193,7 +197,7 @@ dmastart(int chan, int dev, int dir, void *src, void *dst, int len)
|
||||||
cb->txfrlen = len;
|
cb->txfrlen = len;
|
||||||
cb->stride = 0;
|
cb->stride = 0;
|
||||||
cb->nextconbk = 0;
|
cb->nextconbk = 0;
|
||||||
cachedwbse(cb, sizeof(Cb));
|
dmaflush(1, cb, sizeof(Cb));
|
||||||
ctlr->regs[Cs] = 0;
|
ctlr->regs[Cs] = 0;
|
||||||
microdelay(1);
|
microdelay(1);
|
||||||
ctlr->regs[Conblkad] = dmaaddr(cb);
|
ctlr->regs[Conblkad] = dmaaddr(cb);
|
||||||
|
@ -220,6 +224,10 @@ dmawait(int chan)
|
||||||
ctlr = &dma[chan];
|
ctlr = &dma[chan];
|
||||||
tsleep(&ctlr->r, dmadone, ctlr, 3000);
|
tsleep(&ctlr->r, dmadone, ctlr, 3000);
|
||||||
ctlr->dmadone = 0;
|
ctlr->dmadone = 0;
|
||||||
|
if(ctlr->flush != nil){
|
||||||
|
dmaflush(0, ctlr->flush, ctlr->len);
|
||||||
|
ctlr->flush = nil;
|
||||||
|
}
|
||||||
r = ctlr->regs;
|
r = ctlr->regs;
|
||||||
DBG dumpdregs("after sleep", r);
|
DBG dumpdregs("after sleep", r);
|
||||||
s = r[Cs];
|
s = r[Cs];
|
||||||
|
@ -233,3 +241,31 @@ dmawait(int chan)
|
||||||
r[Cs] = Int|End;
|
r[Cs] = Int|End;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dmaflush(int clean, void *p, ulong len)
|
||||||
|
{
|
||||||
|
uintptr s = (uintptr)p;
|
||||||
|
uintptr e = (uintptr)p + len;
|
||||||
|
|
||||||
|
if(clean){
|
||||||
|
s &= ~(BLOCKALIGN-1);
|
||||||
|
e += BLOCKALIGN-1;
|
||||||
|
e &= ~(BLOCKALIGN-1);
|
||||||
|
cachedwbse((void*)s, e - s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(s & BLOCKALIGN-1){
|
||||||
|
s &= ~(BLOCKALIGN-1);
|
||||||
|
cachedwbinvse((void*)s, BLOCKALIGN);
|
||||||
|
s += BLOCKALIGN;
|
||||||
|
}
|
||||||
|
if(e & BLOCKALIGN-1){
|
||||||
|
e &= ~(BLOCKALIGN-1);
|
||||||
|
if(e < s)
|
||||||
|
return;
|
||||||
|
cachedwbinvse((void*)e, BLOCKALIGN);
|
||||||
|
}
|
||||||
|
if(s < e)
|
||||||
|
cachedinvse((void*)s, e - s);
|
||||||
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ extern u32int cpidget(void);
|
||||||
extern void cpwr(int cp, int op1, int crn, int crm, int op2, ulong val);
|
extern void cpwr(int cp, int op1, int crn, int crm, int op2, ulong val);
|
||||||
extern void cpwrsc(int op1, int crn, int crm, int op2, ulong val);
|
extern void cpwrsc(int op1, int crn, int crm, int op2, ulong val);
|
||||||
#define cycles(ip) *(ip) = lcycles()
|
#define cycles(ip) *(ip) = lcycles()
|
||||||
|
extern void dmaflush(int, void*, ulong);
|
||||||
extern void dmastart(int, int, int, void*, void*, int);
|
extern void dmastart(int, int, int, void*, void*, int);
|
||||||
extern int dmawait(int);
|
extern int dmawait(int);
|
||||||
extern uintptr dmaaddr(void *va);
|
extern uintptr dmaaddr(void *va);
|
||||||
|
|
|
@ -63,3 +63,5 @@ enum {
|
||||||
ClkPixel,
|
ClkPixel,
|
||||||
ClkPwm,
|
ClkPwm,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define BUSUNKNOWN (-1)
|
||||||
|
|
|
@ -49,8 +49,8 @@ mmuinit(void *a)
|
||||||
/*
|
/*
|
||||||
* map i/o registers
|
* map i/o registers
|
||||||
*/
|
*/
|
||||||
va = VIRTIO;
|
va = soc.virtio;
|
||||||
for(pa = soc.physio; pa < soc.physio+IOSIZE; pa += MiB){
|
for(pa = soc.physio; pa < soc.physio+soc.iosize; pa += MiB){
|
||||||
l1[L1X(va)] = pa|Dom0|L1AP(Krw)|Section;
|
l1[L1X(va)] = pa|Dom0|L1AP(Krw)|Section;
|
||||||
va += MiB;
|
va += MiB;
|
||||||
}
|
}
|
||||||
|
@ -305,7 +305,7 @@ uintptr
|
||||||
cankaddr(uintptr pa)
|
cankaddr(uintptr pa)
|
||||||
{
|
{
|
||||||
if(pa < PHYSDRAM+soc.dramsize)
|
if(pa < PHYSDRAM+soc.dramsize)
|
||||||
return PHYSDRAM+soc.dramsize - pa;
|
return ((uintptr)PHYSDRAM+soc.dramsize) - pa;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,12 @@ typedef struct Mboxes Mboxes;
|
||||||
#define POWERREGS (VIRTIO+0x100000)
|
#define POWERREGS (VIRTIO+0x100000)
|
||||||
|
|
||||||
Soc soc = {
|
Soc soc = {
|
||||||
.dramsize = 0x3F000000,
|
.dramsize = 0x3E000000,
|
||||||
.physio = 0x3F000000,
|
|
||||||
.busdram = 0xC0000000,
|
.busdram = 0xC0000000,
|
||||||
|
.iosize = 0x01000000,
|
||||||
.busio = 0x7E000000,
|
.busio = 0x7E000000,
|
||||||
|
.physio = 0x3F000000,
|
||||||
|
.virtio = VIRTIO,
|
||||||
.armlocal = 0x40000000,
|
.armlocal = 0x40000000,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -164,5 +166,5 @@ wakecpu(uint cpu)
|
||||||
void
|
void
|
||||||
archbcm3link(void)
|
archbcm3link(void)
|
||||||
{
|
{
|
||||||
addclock0link(wdogfeed, HZ);
|
// addclock0link(wdogfeed, HZ);
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,15 +241,16 @@ struct DevConf
|
||||||
|
|
||||||
struct Soc { /* SoC dependent configuration */
|
struct Soc { /* SoC dependent configuration */
|
||||||
ulong dramsize;
|
ulong dramsize;
|
||||||
uintptr physio;
|
|
||||||
uintptr busdram;
|
uintptr busdram;
|
||||||
|
ulong iosize;
|
||||||
uintptr busio;
|
uintptr busio;
|
||||||
|
uintptr physio;
|
||||||
|
uintptr virtio;
|
||||||
uintptr armlocal;
|
uintptr armlocal;
|
||||||
|
uintptr pciwin;
|
||||||
};
|
};
|
||||||
extern Soc soc;
|
extern Soc soc;
|
||||||
|
|
||||||
#define BUSUNKNOWN -1
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GPIO
|
* GPIO
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -144,6 +144,7 @@ extern void wdogoff(void);
|
||||||
|
|
||||||
/* dma */
|
/* dma */
|
||||||
extern uintptr dmaaddr(void*);
|
extern uintptr dmaaddr(void*);
|
||||||
|
extern void dmaflush(int, void*, ulong);
|
||||||
extern void dmastart(int, int, int, void*, void*, int);
|
extern void dmastart(int, int, int, void*, void*, int);
|
||||||
extern int dmawait(int);
|
extern int dmawait(int);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue