bcm, bcm64: add dmaflush() function and make virtio size and virtual address configurable in Soc.virtio and Soc.iosize

This commit is contained in:
cinap_lenrek 2019-07-25 08:41:37 +02:00
parent 4983adfa2c
commit 5a0c2e2d17
10 changed files with 68 additions and 21 deletions

View file

@ -15,8 +15,10 @@
Soc soc = {
.dramsize = 512*MiB,
.physio = 0x20000000,
.busdram = 0x40000000,
.iosize = 16*MiB,
.virtio = VIRTIO,
.physio = 0x20000000,
.busio = 0x7E000000,
.armlocal = 0,
.l1ptedramattrs = Cached | Buffered,

View file

@ -20,8 +20,10 @@ typedef struct Mboxes Mboxes;
Soc soc = {
.dramsize = 0x3F000000, /* was 1024*MiB, but overlaps with physio */
.physio = 0x3F000000,
.busdram = 0xC0000000,
.iosize = 16*MiB,
.virtio = VIRTIO,
.physio = 0x3F000000,
.busio = 0x7E000000,
.armlocal = 0x40000000,
.l1ptedramattrs = Cached | Buffered | L1wralloc | L1sharable,

View file

@ -281,17 +281,17 @@ struct DevConf
struct Soc { /* SoC dependent configuration */
ulong dramsize;
uintptr physio;
ulong iosize;
uintptr busdram;
uintptr busio;
uintptr physio;
uintptr virtio;
uintptr armlocal;
u32int l1ptedramattrs;
u32int l2ptedramattrs;
};
extern Soc soc;
#define BUSUNKNOWN -1
/*
* GPIO
*/

View file

@ -82,6 +82,8 @@ struct Ctlr {
Cb *cb;
Rendez r;
int dmadone;
void *flush;
int len;
};
struct Cb {
@ -108,7 +110,7 @@ dmaaddr(void *va)
static uintptr
dmaioaddr(void *va)
{
return soc.busio | ((uintptr)va - VIRTIO);
return soc.busio | ((uintptr)va - soc.virtio);
}
static void
@ -164,26 +166,28 @@ dmastart(int chan, int dev, int dir, void *src, void *dst, int len)
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;
ti = 0;
switch(dir){
case DmaD2M:
cachedwbinvse(dst, len);
ctlr->flush = dst;
ti = Srcdreq | Destinc;
cb->sourcead = dmaioaddr(src);
cb->destad = dmaaddr(dst);
break;
case DmaM2D:
cachedwbse(src, len);
ctlr->flush = nil;
dmaflush(1, src, len);
ti = Destdreq | Srcinc;
cb->sourcead = dmaaddr(src);
cb->destad = dmaioaddr(dst);
break;
case DmaM2M:
cachedwbse(src, len);
cachedwbinvse(dst, len);
ctlr->flush = dst;
dmaflush(1, src, len);
ti = Srcinc | Destinc;
cb->sourcead = dmaaddr(src);
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->stride = 0;
cb->nextconbk = 0;
cachedwbse(cb, sizeof(Cb));
dmaflush(1, cb, sizeof(Cb));
ctlr->regs[Cs] = 0;
microdelay(1);
ctlr->regs[Conblkad] = dmaaddr(cb);
@ -220,6 +224,10 @@ dmawait(int chan)
ctlr = &dma[chan];
tsleep(&ctlr->r, dmadone, ctlr, 3000);
ctlr->dmadone = 0;
if(ctlr->flush != nil){
dmaflush(0, ctlr->flush, ctlr->len);
ctlr->flush = nil;
}
r = ctlr->regs;
DBG dumpdregs("after sleep", r);
s = r[Cs];
@ -233,3 +241,31 @@ dmawait(int chan)
r[Cs] = Int|End;
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);
}

View file

@ -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 cpwrsc(int op1, int crn, int crm, int op2, ulong val);
#define cycles(ip) *(ip) = lcycles()
extern void dmaflush(int, void*, ulong);
extern void dmastart(int, int, int, void*, void*, int);
extern int dmawait(int);
extern uintptr dmaaddr(void *va);

View file

@ -63,3 +63,5 @@ enum {
ClkPixel,
ClkPwm,
};
#define BUSUNKNOWN (-1)

View file

@ -49,8 +49,8 @@ mmuinit(void *a)
/*
* map i/o registers
*/
va = VIRTIO;
for(pa = soc.physio; pa < soc.physio+IOSIZE; pa += MiB){
va = soc.virtio;
for(pa = soc.physio; pa < soc.physio+soc.iosize; pa += MiB){
l1[L1X(va)] = pa|Dom0|L1AP(Krw)|Section;
va += MiB;
}
@ -305,7 +305,7 @@ uintptr
cankaddr(uintptr pa)
{
if(pa < PHYSDRAM+soc.dramsize)
return PHYSDRAM+soc.dramsize - pa;
return ((uintptr)PHYSDRAM+soc.dramsize) - pa;
return 0;
}

View file

@ -17,10 +17,12 @@ typedef struct Mboxes Mboxes;
#define POWERREGS (VIRTIO+0x100000)
Soc soc = {
.dramsize = 0x3F000000,
.physio = 0x3F000000,
.dramsize = 0x3E000000,
.busdram = 0xC0000000,
.iosize = 0x01000000,
.busio = 0x7E000000,
.physio = 0x3F000000,
.virtio = VIRTIO,
.armlocal = 0x40000000,
};
@ -164,5 +166,5 @@ wakecpu(uint cpu)
void
archbcm3link(void)
{
addclock0link(wdogfeed, HZ);
// addclock0link(wdogfeed, HZ);
}

View file

@ -241,15 +241,16 @@ struct DevConf
struct Soc { /* SoC dependent configuration */
ulong dramsize;
uintptr physio;
uintptr busdram;
ulong iosize;
uintptr busio;
uintptr physio;
uintptr virtio;
uintptr armlocal;
uintptr pciwin;
};
extern Soc soc;
#define BUSUNKNOWN -1
/*
* GPIO
*/

View file

@ -144,6 +144,7 @@ extern void wdogoff(void);
/* dma */
extern uintptr dmaaddr(void*);
extern void dmaflush(int, void*, ulong);
extern void dmastart(int, int, int, void*, void*, int);
extern int dmawait(int);