M alphapc/arch164.c => alphapc/arch164.c +8 -3
@@ 54,15 54,17 @@ coreinit(void)
}
coresave[0] = core[0x140/4];
- /* direct map bottom 2G PCI target space to KZERO in window 1 */
- wind[0x500/4] = KZERO|1;
- wind[0x540/4] = 0x7ff00000;
+#ifdef notdef
+ /* direct map bottom 1G PCI target space to KZERO in window 1 */
+ wind[0x500/4] = PCIWINDOW|1;
+ wind[0x540/4] = 0x3ff00000;
wind[0x580/4] = 0;
/* disable other windows */
wind[0x400/4] = 0;
wind[0x600/4] = 0;
wind[0x700/4] = 0;
+#endif /* notdef */
/* clear error state */
core[0x8200/4] = 0x7ff;
@@ 263,6 265,7 @@ outb2117x(int port, int val)
{
mb();
*(uchar*)(iobase(port)) = val;
+ mb();
}
void
@@ 270,6 273,7 @@ outs2117x(int port, ushort val)
{
mb();
*(ushort*)(iobase(port)) = val;
+ mb();
}
void
@@ 277,6 281,7 @@ outl2117x(int port, ulong val)
{
mb();
*(ulong*)(iobase(port)) = val;
+ mb();
}
void
M alphapc/devfloppy.c => alphapc/devfloppy.c +2 -37
@@ 118,10 118,8 @@ Dirtab floppydir[]={
static void
fldump(void)
{
-mb();
DPRINT("sra %ux srb %ux dor %ux msr %ux dir %ux\n", inb(Psra), inb(Psrb),
inb(Pdor), inb(Pmsr), inb(Pdir));
-mb();
}
/*
@@ 146,8 144,6 @@ floppyreset(void)
FDrive *dp;
FType *t;
ulong maxtsize;
-
- dmainit(DMAchan);
floppysetup0(&fl);
@@ 163,6 159,8 @@ floppyreset(void)
maxtsize = t->tsize;
}
+ dmainit(DMAchan, maxtsize);
+
/*
* allocate the drive storage
*/
@@ 174,9 172,7 @@ floppyreset(void)
*/
fl.motor = 0;
delay(10);
-mb();
outb(Pdor, fl.motor | Fintena | Fena);
-mb();
delay(10);
/*
@@ 267,23 263,15 @@ changed(Chan *c, FDrive *dp)
/*
* if floppy has changed or first time through
*/
-mb();
if((inb(Pdir)&Fchange) || dp->vers == 0){
-mb();
DPRINT("changed\n");
fldump();
dp->vers++;
floppysetdef(dp);
start = dp->t;
dp->confused = 1; /* make floppyon recal */
-DPRINT("b4 floppyon:\n");
-fldump();
floppyon(dp);
-DPRINT("after floppyon:\n");
-fldump();
floppyseek(dp, dp->t->heads*dp->t->tsize);
-DPRINT("after floppyseek:\n");
-fldump();
while(waserror()){
while(++dp->t){
if(dp->t == &floppytype[nelem(floppytype)])
@@ 486,9 474,7 @@ floppyon(FDrive *dp)
/* start motor and select drive */
alreadyon = fl.motor & MOTORBIT(dp->dev);
fl.motor |= MOTORBIT(dp->dev);
-mb();
outb(Pdor, fl.motor | Fintena | Fena | dp->dev);
-mb();
if(!alreadyon){
/* wait for drive to spin up */
tsleep(&dp->r, return0, 0, 750);
@@ 500,9 486,7 @@ mb();
/* set transfer rate */
if(fl.rate != dp->t->rate){
fl.rate = dp->t->rate;
-mb();
outb(Pdsr, fl.rate);
-mb();
}
/* get drive to a known cylinder */
@@ 521,9 505,7 @@ static void
floppyoff(FDrive *dp)
{
fl.motor &= ~MOTORBIT(dp->dev);
-mb();
outb(Pdor, fl.motor | Fintena | Fena | dp->dev);
-mb();
}
/*
@@ 538,10 520,8 @@ floppycmd(void)
fl.nstat = 0;
for(i = 0; i < fl.ncmd; i++){
for(tries = 0; ; tries++){
-mb();
if((inb(Pmsr)&(Ffrom|Fready)) == Fready)
break;
-mb();
if(tries > 1000){
DPRINT("cmd %ux can't be sent (%d)\n", fl.cmd[0], i);
fldump();
@@ 552,9 532,7 @@ mb();
}
microdelay(8); /* for machine independence */
}
-mb();
outb(Pfdata, fl.cmd[i]);
-mb();
}
return 0;
}
@@ 576,9 554,7 @@ floppyresult(void)
for(i = 0; i < sizeof(fl.stat); i++){
/* wait for status byte */
for(tries = 0; ; tries++){
-mb();
s = inb(Pmsr)&(Ffrom|Fready);
-mb();
if(s == Fready){
fl.nstat = i;
return fl.nstat;
@@ 593,10 569,7 @@ mb();
}
microdelay(8); /* for machine independence */
}
-mb();
fl.stat[i] = inb(Pfdata);
-mb();
-// print("stat[%d]: %.2ux\n", i, fl.stat[i]);
}
fl.nstat = sizeof(fl.stat);
return fl.nstat;
@@ 686,9 659,7 @@ floppyrecal(FDrive *dp)
return -1;
floppywait();
if(fl.nstat < 2){
-mb();
DPRINT("recalibrate: confused %ux\n", inb(Pmsr));
-mb();
fl.confused = 1;
return -1;
}
@@ 729,13 700,9 @@ floppyrevive(void)
splhi();
fl.ncmd = 1;
fl.cmd[0] = 0;
-mb();
outb(Pdor, 0);
-mb();
delay(10);
-mb();
outb(Pdor, Fintena|Fena);
-mb();
delay(10);
spllo();
fl.motor = 0;
@@ 747,9 714,7 @@ mb();
dp->confused = 1;
/* set rate to a known value */
-mb();
outb(Pdsr, 0);
-mb();
fl.rate = 0;
DPRINT("floppyrevive out\n");
M alphapc/dma.c => alphapc/dma.c +37 -35
@@ 9,23 9,6 @@ typedef struct DMAport DMAport;
typedef struct DMA DMA;
typedef struct DMAxfer DMAxfer;
-enum
-{
- /*
- * the byte registers for DMA0 are all one byte apart
- */
- Dma0= 0x00,
- Dma0status= Dma0+0x8, /* status port */
- Dma0reset= Dma0+0xD, /* reset port */
-
- /*
- * the byte registers for DMA1 are all two bytes apart (why?)
- */
- Dma1= 0xC0,
- Dma1status= Dma1+2*0x8, /* status port */
- Dma1reset= Dma1+2*0xD, /* reset port */
-};
-
/*
* state of a dma transfer
*/
@@ 33,6 16,7 @@ struct DMAxfer
{
ulong bpa; /* bounce buffer physical address */
void* bva; /* bounce buffer virtual address */
+ int blen; /* bounce buffer length */
void* va; /* virtual address destination/src */
long len; /* bytes to be transferred */
int isread;
@@ 84,29 68,42 @@ DMA dma[2] = {
* initialisation routines of any devices which require DMA to ensure
* the allocated bounce buffers are below the 16MB limit.
*/
-void
-dmainit(int chan)
+int
+dmainit(int chan, int maxtransfer)
{
DMA *dp;
DMAxfer *xp;
- ulong v;
+
+ if(maxtransfer > 64*1024)
+ maxtransfer = 64*1024;
dp = &dma[(chan>>2)&1];
chan = chan & 3;
xp = &dp->x[chan];
- if(xp->bva != nil)
- return;
-
- v = (ulong)xalloc(BY2PG+BY2PG);
- if(v == 0 || PADDR(v) >= 16*MB){
- print("dmainit: chan %d: 0x%luX out of range\n", chan, v);
- xfree((void*)v);
- v = 0;
+ if(xp->bva != nil){
+ if(xp->blen < maxtransfer)
+ return 1;
+ return 0;
}
- xp->bva = (void*)ROUND(v, BY2PG);
+
+ xp->bva = xspanalloc(maxtransfer, BY2PG, 64*1024);
+ if(xp->bva == nil)
+ return 1;
xp->bpa = PADDR(xp->bva);
+ if(xp->bpa >= 16*MB){
+ /*
+ * This will panic with the current
+ * implementation of xspanalloc().
+ xfree(xp->bva);
+ */
+ xp->bva = nil;
+ return 1;
+ }
+ xp->blen = maxtransfer;
xp->len = 0;
xp->isread = 0;
+
+ return 0;
}
/*
@@ 133,16 130,17 @@ dmasetup(int chan, void *va, long len, int isread)
/*
* if this isn't kernel memory or crossing 64k boundary or above 16 meg
- * use the allocated low memory page.
+ * use the bounce buffer.
*/
+#ifdef notdef
pa = PADDR(va);
if((((ulong)va)&0xF0000000) != KZERO
|| (pa&0xFFFF0000) != ((pa+len)&0xFFFF0000)
|| pa >= 16*MB) {
if(xp->bva == nil)
return -1;
- if(len > BY2PG)
- len = BY2PG;
+ if(len > xp->blen)
+ len = xp->blen;
if(!isread)
memmove(xp->bva, va, len);
xp->va = va;
@@ 152,17 150,21 @@ dmasetup(int chan, void *va, long len, int isread)
}
else
xp->len = 0;
+#else
+ pa = PCIWADDR(va);
+#endif /* notdef */
/*
* this setup must be atomic
*/
- ilock(dp);
mode = (isread ? 0x44 : 0x48) | chan;
- outb(dp->mode, mode); /* single mode dma (give CPU a chance at mem) */
- outb(dp->page[chan], pa>>16);
+ ilock(dp);
outb(dp->cbp, 0); /* set count & address to their first byte */
+ outb(dp->mode, mode); /* single mode dma (give CPU a chance at mem) */
outb(dp->addr[chan], pa>>dp->shift); /* set address */
outb(dp->addr[chan], pa>>(8+dp->shift));
+ outb(dp->page[chan], pa>>16);
+outb(0x400|dp->page[chan], pa>>24);
outb(dp->count[chan], (len>>dp->shift)-1); /* set count */
outb(dp->count[chan], ((len>>dp->shift)-1)>>8);
outb(dp->sbm, chan); /* enable the channel */
M alphapc/ether2114x.c => alphapc/ether2114x.c +5 -8
@@ 21,9 21,6 @@
/* nasty PCI DMA hack... */
-#undef PADDR
-#define PADDR(a) ((ulong)(a))
-
#define DEBUG 0
#define debug if(DEBUG)print
@@ 380,7 377,7 @@ txstart(Ether* ether)
ctlr->tdr[PREV(ctlr->tdrh, ctlr->ntdr)].control &= ~Ic;
des = &ctlr->tdr[ctlr->tdrh];
des->bp = bp;
- des->addr = PADDR(bp->rp);
+ des->addr = PCIWADDR(bp->rp);
des->control |= control;
ctlr->ntq++;
coherence();
@@ 465,7 462,7 @@ interrupt(Ureg*, void* arg)
des->bp->wp = des->bp->rp+len;
etheriq(ether, des->bp, 1);
des->bp = bp;
- des->addr = PADDR(bp->rp);
+ des->addr = PCIWADDR(bp->rp);
}
des->control &= Er;
@@ 574,17 571,17 @@ ctlrinit(Ether* ether)
des->bp = allocb(ROUNDUP(sizeof(Etherpkt)+4, 4));
des->status = Own;
des->control = ROUNDUP(sizeof(Etherpkt)+4, 4);
- des->addr = PADDR(des->bp->rp);
+ des->addr = PCIWADDR(des->bp->rp);
}
ctlr->rdr[ctlr->nrdr-1].control |= Er;
ctlr->rdrx = 0;
- csr32w(ctlr, 3, PADDR(ctlr->rdr));
+ csr32w(ctlr, 3, PCIWADDR(ctlr->rdr));
ctlr->tdr = xspanalloc(ctlr->ntdr*sizeof(Des), 8*sizeof(ulong), 0);
ctlr->tdr[ctlr->ntdr-1].control |= Er;
ctlr->tdrh = 0;
ctlr->tdri = 0;
- csr32w(ctlr, 4, PADDR(ctlr->tdr));
+ csr32w(ctlr, 4, PCIWADDR(ctlr->tdr));
ctlr->mask = Nis|Ais|Fbe|Rwt|Rps|Ru|Ri|Unf|Tjt|Tps|Ti;
csr32w(ctlr, 7, ctlr->mask);
M alphapc/fns.h => alphapc/fns.h +1 -1
@@ 15,7 15,7 @@ void cserve(ulong, ulong);
int dmacount(int);
int dmadone(int);
void dmaend(int);
-void dmainit(int);
+int dmainit(int, int);
long dmasetup(int, void*, long, int);
void evenaddr(ulong);
void fataltrap(Ureg *, char *);
M alphapc/io.h => alphapc/io.h +3 -0
@@ 202,3 202,6 @@ typedef struct SCSIdev {
char* type;
Scsiio (*reset)(int, ISAConf*);
} SCSIdev;
+
+#define PCIWINDOW 0x40000000
+#define PCIWADDR(va) (PADDR(va)+PCIWINDOW)
M alphapc/main.c => alphapc/main.c +1 -1
@@ 54,11 54,11 @@ main(void)
percpu[32] |= (0<<16); /* default action */
#endif
- pageinit();
procinit0();
initseg();
links();
chandevreset();
+ pageinit();
swapinit();
userinit();
schedinit();
M pc/devlml.c => pc/devlml.c +359 -38
@@ 13,10 13,8 @@
enum{
Q819,
Q856,
- Qi22,
Q060,
Q067,
- Qstat,
Qvideo,
Qjframe,
};
@@ 25,10 23,8 @@ static Dirtab viddir[]={
// name, qid, size, mode
"vid819", {Q819}, 0, 0644,
"vid856", {Q856}, 0, 0644,
- "vidi22", {Qi22}, 0, 0644,
"vid060", {Q060}, 0, 0644,
"vid067", {Q067}, 0, 0644,
- "vidstat", {Qstat}, 0, 0444,
"video", {Qvideo}, 0, 0666,
"jframe", {Qjframe}, 0, 0666,
};
@@ 36,7 32,318 @@ static Dirtab viddir[]={
CodeData * codeData;
MjpgDrv * mjpgDrv;
-static void lmlintr(Ureg *ur, void *arg);
+static void
+lml33_i2c_pause(void) {
+
+ microdelay(I2C_DELAY);
+}
+
+static void
+lml33_i2c_waitscl(void) {
+ int i;
+ ulong a;
+
+ for(i=0;;i++) {
+ a = readl(pciBaseAddr + ZR36057_I2C_BUS);
+ if (a & ZR36057_I2C_SCL) break;
+ if (i>I2C_TIMEOUT) error(Eio);
+ }
+}
+
+static void
+lml33_i2c_start(void) {
+
+ writel(ZR36057_I2C_SCL|ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS);
+ lml33_i2c_waitscl();
+ lml33_i2c_pause();
+
+ writel(ZR36057_I2C_SCL, pciBaseAddr + ZR36057_I2C_BUS);
+ lml33_i2c_pause();
+
+ writel(0, pciBaseAddr + ZR36057_I2C_BUS);
+ lml33_i2c_pause();
+}
+
+static void
+lml33_i2c_stop(void) {
+ // the clock should already be low, make sure data is
+ writel(0, pciBaseAddr + ZR36057_I2C_BUS);
+ lml33_i2c_pause();
+
+ // set clock high and wait for device to catch up
+ writel(ZR36057_I2C_SCL, pciBaseAddr + ZR36057_I2C_BUS);
+ lml33_i2c_waitscl();
+ lml33_i2c_pause();
+
+ // set the data high to indicate the stop bit
+ writel(ZR36057_I2C_SCL|ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS);
+ lml33_i2c_pause();
+}
+
+static void lml33_i2c_wrbit(int bit) {
+ if (bit){
+ writel(ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS); // set data
+ lml33_i2c_pause();
+ writel(ZR36057_I2C_SDA|ZR36057_I2C_SCL, pciBaseAddr + ZR36057_I2C_BUS);
+ lml33_i2c_waitscl();
+ lml33_i2c_pause();
+ writel(ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS);
+ lml33_i2c_pause();
+ } else {
+ writel(0, pciBaseAddr + ZR36057_I2C_BUS); // clr data
+ lml33_i2c_pause();
+ writel(ZR36057_I2C_SCL, pciBaseAddr + ZR36057_I2C_BUS);
+ lml33_i2c_waitscl();
+ lml33_i2c_pause();
+ writel(0, pciBaseAddr + ZR36057_I2C_BUS);
+ lml33_i2c_pause();
+ }
+}
+
+static int
+lml33_i2c_rdbit(void) {
+ int bit;
+ // the clk line should be low
+
+ // ensure we are not asserting the data line
+ writel(ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS);
+ lml33_i2c_pause();
+
+ // set the clock high and wait for device to catch up
+ writel(ZR36057_I2C_SDA|ZR36057_I2C_SCL, pciBaseAddr + ZR36057_I2C_BUS);
+ lml33_i2c_waitscl();
+ lml33_i2c_pause();
+
+ // the data line should be a valid bit
+ bit = readl(pciBaseAddr+ZR36057_I2C_BUS);
+ if (bit & ZR36057_I2C_SDA){
+ bit = 1;
+ } else {
+ bit = 0;
+ }
+
+ // set the clock low to indicate end of cycle
+ writel(ZR36057_I2C_SDA, pciBaseAddr + ZR36057_I2C_BUS);
+ lml33_i2c_pause();
+
+ return bit;
+}
+
+static int
+lml33_i2c_rdbyte(uchar *v) {
+ int i, ack;
+ uchar res;
+
+ res = 0;
+ for (i=0;i<8;i++){
+ res = res << 1;
+ res += lml33_i2c_rdbit();
+ }
+
+ ack = lml33_i2c_rdbit();
+
+ *v = res;
+
+ return ack;
+}
+
+static int
+lml33_i2c_wrbyte(uchar v) {
+ int i, ack;
+
+ for (i=0;i<8;i++){
+ lml33_i2c_wrbit(v & 0x80);
+ v = v << 1;
+ }
+
+ ack = lml33_i2c_rdbit();
+
+ return ack;
+}
+
+static void
+lml33_i2c_write_bytes(uchar addr, uchar sub, uchar *bytes, long num) {
+ int ack;
+ long i;
+
+ lml33_i2c_start();
+
+ ack = lml33_i2c_wrbyte(addr);
+ if (ack == 1) error(Eio);
+
+ ack = lml33_i2c_wrbyte(sub);
+ if (ack == 1) error(Eio);
+
+ for(i=0;i<num;i+=1){
+ ack = lml33_i2c_wrbyte(bytes[i]);
+ if (ack == 1) error(Eio);
+ }
+
+ lml33_i2c_stop();
+}
+
+static uchar
+lml33_i2c_rd8(int addr, int sub)
+{
+ int ack;
+ uchar msb;
+
+ lml33_i2c_start();
+
+ ack = lml33_i2c_wrbyte(addr);
+ if (ack == 1){
+ lml33_i2c_stop();
+ error(Eio);
+ }
+
+ ack = lml33_i2c_wrbyte(sub);
+ if (ack == 1){
+ lml33_i2c_stop();
+ error(Eio);
+ }
+
+ lml33_i2c_start();
+
+ ack = lml33_i2c_wrbyte(addr+1);
+ if (ack == 1){
+ lml33_i2c_stop();
+ error(Eio);
+ }
+
+ ack = lml33_i2c_rdbyte(&msb);
+ if (ack == 0){
+ lml33_i2c_stop();
+ error(Eio);
+ }
+
+ lml33_i2c_stop();
+
+ return msb;
+}
+
+/*
+ * The following mapping applies for the guests in the LML33
+ *
+ * Guest Device
+ * 0 zr36060
+ * uses subaddress GADR[0..1]
+ * 1 zr36060 START#
+ * 2 -
+ * 3 zr36060 RESET#
+ * 4 -
+ * 5 -
+ * 6 -
+ * 7 -
+ */
+
+// lml33_post_idle waits for the guest bus to become free
+static int
+lml33_post_idle(void) {
+ ulong a;
+ int timeout;
+
+ for(timeout = 0;;timeout += 1){
+ a = readl(pciBaseAddr + ZR36057_POST_OFFICE);
+ if ((a & ZR36057_POST_PEND) == 0)
+ return a;
+ if (timeout == GUEST_TIMEOUT)
+ return -1;
+ }
+}
+
+// lml33_post_write writes a byte to a guest using postoffice mechanism
+static void
+lml33_post_write(int guest, int reg, int v) {
+ int w;
+
+ // wait for postoffice not busy
+ lml33_post_idle();
+
+ // Trim the values, just in case
+ guest &= 0x07;
+ reg &= 0x07;
+ v &= 0xFF;
+
+ // write postoffice operation
+ w = ZR36057_POST_DIR + (guest<<20) + (reg<<16) + v;
+ writel(w, pciBaseAddr + ZR36057_POST_OFFICE);
+
+ // wait for postoffice not busy
+ w = lml33_post_idle();
+
+ // decide if write went ok
+ if (w == -1) error(Eio);
+}
+
+// lml33_post_read reads a byte from a guest using postoffice mechanism
+static uchar
+lml33_post_read(int guest, int reg) {
+ int w;
+
+ // wait for postoffice not busy
+ lml33_post_idle();
+
+ // Trim the values, just in case
+ guest &= 0x07;
+ reg &= 0x07;
+
+ // write postoffice operation
+ w = (guest<<20) + (reg<<16);
+ writel(w, pciBaseAddr + ZR36057_POST_OFFICE);
+
+ // wait for postoffice not busy, get result
+ w = lml33_post_idle();
+
+ // decide if read went ok
+ if (w == -1) error(Eio);
+
+ return (uchar)(w & 0xFF);
+}
+
+static void
+lml33_zr060_write(int reg, int v) {
+ int guest_id;
+
+ guest_id = GID060;
+
+ lml33_post_write(guest_id, 1, reg>>8 & 0x03);
+ lml33_post_write(guest_id, 2, reg & 0xff);
+ lml33_post_write(guest_id, 3, v);
+}
+
+static uchar
+lml33_zr060_read(int reg) {
+ int guest_id;
+
+ guest_id = GID060;
+
+ lml33_post_write(guest_id, 1, reg>>8 & 0x03);
+ lml33_post_write(guest_id, 2, reg & 0xff);
+
+ return lml33_post_read(guest_id, 3);
+}
+
+long
+chipread(long addr, char *buf, long n, long off) {
+ long i;
+
+ for (i = 0; i < n; i++) {
+ *buf++ = lml33_i2c_rd8(addr, off++);
+ }
+ return i;
+}
+
+long
+post060read(char *buf, long n, long off) {
+ long i;
+
+ for (i = 0; i < n; i++) {
+ *buf++ = lml33_zr060_read(off++);
+ }
+ return i;
+}
+
+static void lmlintr(Ureg *, void *);
static void
vidreset(void)
@@ 44,6 351,11 @@ vidreset(void)
ulong regpa;
int i;
+ pcidev = pcimatch(nil, PCI_VENDOR_ZORAN, PCI_DEVICE_ZORAN_36067);
+ if (pcidev == nil) {
+ print("No zr36067 found.\n");
+ return;
+ }
codeData = (CodeData*)xspanalloc(sizeof(CodeData), BY2PG, 0);
if (codeData == nil) {
print("devlml: xspanalloc(%ux, %ux, 0)\n", sizeof(CodeData), BY2PG);
@@ 61,7 373,7 @@ vidreset(void)
codeData->statCom[i] = PADDR(&(codeData->fragmDescr[i]));
codeData->statComInitial[i] = codeData->statCom[i];
codeData->fragmDescr[i].fragmAddress =
- (H33_Fragment *)PADDR(&(codeData->frag[i]));
+ (Fragment *)PADDR(&(codeData->frag[i]));
// Length is in double words, in position 1..20
codeData->fragmDescr[i].fragmLength = (FRAGSIZE >> 1) | FRAGM_FINAL_B;
}
@@ 71,39 383,29 @@ vidreset(void)
print("LML33: can't allocate dynamic memory for MjpgDrv\n");
return;
}
- if((lml33Board = xallocz(sizeof(LML33Board), 0)) == nil) {
- print("LML33: can't allocate dynamic memory for lml33Board\n");
- return;
- }
print("initializing LML33 board...");
- lml33Board->pcidev = pcimatch(nil, PCI_VENDOR_ZORAN, PCI_DEVICE_ZORAN_36067);
- if (lml33Board->pcidev == nil) {
- print("zr36067 not found. Install aborted.\n");
- return;
- }
- lml33Board->pciPhysBaseAddr =
- (void *)(lml33Board->pcidev->mem[0].bar & ~0x0F);
+ pciPhysBaseAddr = (void *)(pcidev->mem[0].bar & ~0x0F);
- print("zr36067 found at %lux\n", lml33Board->pciPhysBaseAddr);
+ print("zr36067 found at %lux\n", pciPhysBaseAddr);
- regpa = upamalloc(lml33Board->pcidev->mem[0].bar & ~0x0F, lml33Board->pcidev->mem[0].size, 0);
+ regpa = upamalloc(pcidev->mem[0].bar & ~0x0F, pcidev->mem[0].size, 0);
if (regpa == 0) {
print("lml: failed to map registers\n");
return;
}
- lml33Board->pciBaseAddr = KADDR(regpa);
+ pciBaseAddr = (ulong)KADDR(regpa);
// make sure the device will respond to mem accesses
// (pcicmd_master | pcicmd_memory) -- probably superfluous
-// pcicfgw32(lml33Board->pcidev, PciPCR, 0x04 | 0x02);
+// pcicfgw32(pcidev, PciPCR, 0x04 | 0x02);
// set bus latency -- probably superfluous
-// pcicfgw8(lml33Board->pcidev, PciLTR, 64);
+// pcicfgw8(pcidev, PciLTR, 64);
// Interrupt handler
- intrenable(lml33Board->pcidev->intl, lmlintr, lml33Board, lml33Board->pcidev->tbdf);
+ intrenable(pcidev->intl, lmlintr, nil, pcidev->tbdf);
print("LML33 Installed\n");
return;
@@ 134,14 436,10 @@ vidopen(Chan *c, int omode)
switch(c->qid.path){
case Q819:
case Q856:
- case Qi22:
case Q060:
case Q067:
// allow one open per file
break;
- case Qstat:
- // allow many opens
- break;
case Qvideo:
case Qjframe:
// allow one open total for these two
@@ 156,10 454,8 @@ vidclose(Chan *c)
switch(c->qid.path){
case Q819:
case Q856:
- case Qi22:
case Q060:
case Q067:
- case Qstat:
case Qvideo:
case Qjframe:
authclose(c);
@@ 167,17 463,23 @@ vidclose(Chan *c)
}
static long
-vidread(Chan *c, void *buf, long n, vlong off)
-{
+vidread(Chan *c, void *buf, long n, vlong off) {
+
switch(c->qid.path){
case Q819:
+ if (off < 0 || off + n > 20)
+ return 0;
+ return chipread(BT819Addr, buf, n, off);
case Q856:
- case Qi22:
+ if (off < 0xda || off + n > 0xe0)
+ return 0;
+ return chipread(BT856Addr, buf, n, off);
case Q060:
+ return post060read(buf, n, off);
case Q067:
- return chipread(c, buf, n, off);
- case Qstat:
- return statread(c, buf, n, off);
+ if (off < 0 || off + n > 20 || (off & 0x3) || n != 4) return 0;
+ *(long *)buf = readl(pciBaseAddr + off);
+ return 4;
case Qvideo:
case Qjframe:
return videoread(c, buf, n, off);
@@ 187,6 489,26 @@ vidread(Chan *c, void *buf, long n, vlong off)
static long
vidwrite(Chan *c, void *va, long n, vlong off)
{
+
+ switch(c->qid.path){
+ case Q819:
+ if (off < 0 || off + n > 20)
+ return 0;
+ return chipwrite(BT819Addr, buf, n, off);
+ case Q856:
+ if (off < 0xda || off + n > 0xe0)
+ return 0;
+ return chipwrite(BT856Addr, buf, n, off);
+ case Q060:
+ return post060write(buf, n, off);
+ case Q067:
+ if (off < 0 || off + n > 20 || (off & 0x3) || n != 4) return 0;
+ writel(*(long *)buf, pciBaseAddr + off);
+ return 4;
+ case Qvideo:
+ case Qjframe:
+ return videowrite(c, buf, n, off);
+ }
}
Dev viddevtab = {
@@ 211,9 533,8 @@ Dev viddevtab = {
};
static void
-lmlintr(Ureg *ur, void *arg)
+lmlintr(Ureg *ur, void *)
{
- LML33Board *lml33Board = (Lml33Board *)arg;
-
+
}
M pc/devlml.h => pc/devlml.h +47 -218
@@ 11,52 11,56 @@
// The following values can be modified to tune/set default behaviour of the
// driver.
-// The number of uS delay in I2C state transitions
-#define H33_I2C_DELAY 10
+// The number of uS delay in I2C state transitions (probably >= 10)
+#define I2C_DELAY 15
// The amount of spinning to do before the I2C bus is timed out
-#define H33_I2C_TIMEOUT 10000000
+#define I2C_TIMEOUT 10000000
// The amount of spinning to do before the guest bus is timed out
-#define H33_GUEST_TIMEOUT 10000000
+#define GUEST_TIMEOUT 10000000
// The amount of spinning to do before the polling of the still
// transfer port is aborted.
-#define H33_STILL_TIMEOUT 1000000
+#define STILL_TIMEOUT 1000000
// The following number is the maximum number of cards permited. Each
// card found is mapped to a device minor number starting from 0.
-#define H33_MAX_CARDS 1
+#define MAX_CARDS 1
// The following is the number of device types supported.
-#define H33_DEVICE_COUNT 2
+#define DEVICE_COUNT 2
// The number of 8K pages per buffer, we will allocate four buffers,
// locked into memory whenever the device is open so modify with care.
-#define H33_PAGES 32
+#define PAGES 32
// The following are the datastructures needed by the device.
+#define ZR36057_I2C_BUS 0x044
+// which bit of ZR36057_I2C_BUS is which
+#define ZR36057_I2C_SCL 1
+#define ZR36057_I2C_SDA 2
-// A H33_Device records the properties of the various card types supported.
+// A Device records the properties of the various card types supported.
typedef struct {
int number; // The H33_CARDTYPE_ assigned
char *card_name; // A string name
int zr060addr; // Which guest bus address for the ZR36060
-} H33_Device;
+} Device;
// An entry in the fragment table
typedef struct {
ulong address; // bus address of page
int length; // length of page
-} H33_RingPage;
+} RingPage;
// The structure that we will use to tell the '57 about the buffers
-// The sizeof(H33_RingData) should not exceed page size
+// The sizeof(RingData) should not exceed page size
typedef struct {
void *buffer[4];
ulong i_stat_com[4];
- H33_RingPage ring_pages[4][H33_PAGES];
-} H33_RingData;
+ RingPage ring_pages[4][PAGES];
+} RingData;
typedef struct {
int expect; // the buffer the int routine expects next
@@ 64,7 68,7 @@ typedef struct {
int filled; // the current number of filled buffers
int pages; // the number of complete pages
int remainder; // the number of bytes in incomplete page
-} H33_RingPtr;
+} RingPtr;
// The remainder of the #defs are constants which should not need changing.
@@ 72,142 76,17 @@ typedef struct {
// these really belong in pci.h
#define PCI_VENDOR_ZORAN 0x11de
#define PCI_DEVICE_ZORAN_36057 0x6057
+#define PCI_DEVICE_ZORAN_36067 PCI_DEVICE_ZORAN_36057
-// The ZR36057 is mapped into a 4Kbyte block of the address space
-// starting at PCI_BASE_ADDRESS_0. Its application specific registers
-// are layed out within that space as follows.
-#define ZR36057_VFEND_HORCON 0x000
-#define ZR36057_VFEND_VERCON 0x004
-#define ZR36057_VFEND_SCLPIX 0x008
-#define ZR36057_VDISP_TOP 0x00c
-#define ZR36057_VDISP_BOT 0x010
-#define ZR36057_VSTRD_GRB 0x014
-#define ZR36057_VDISP_CONF 0x018
-#define ZR36057_MASK_TOP 0x01c
-#define ZR36057_MASK_BOT 0x020
-#define ZR36057_OVRLY_CTL 0x024
-#define ZR36057_SYS_PCI 0x028
-#define ZR36057_GPIO_CTL 0x02c
-#define ZR36057_MPEG_SRCW 0x030
-#define ZR36057_MPEG_CTFR_CTL 0x034
-#define ZR36057_MPEG_MEM_PTR 0x038
-#define ZR36057_INTR_STAT 0x03c
-#define ZR36057_INTR_CTL 0x040
-#define ZR36057_I2C_BUS 0x044
-#define ZR36057_JPEG_MODE_CTL 0x100
-#define ZR36057_JPEG_PROC_CTL 0x104
-#define ZR36057_VSYNC_PARM 0x108
-#define ZR36057_HSYNC_PARM 0x10c
-#define ZR36057_HOR_ACTIVE 0x110
-#define ZR36057_VER_ACTIVE 0x114
-#define ZR36057_FIELD_PROC 0x118
-#define ZR36057_JPEG_CODE_BASE 0x11C
-#define ZR36057_JPEG_FIFO_THRHLD 0x120
-#define ZR36057_JPEG_GUESTID 0x124
-#define ZR36057_GUEST_CTL 0x12c
-#define ZR36057_POST_OFFICE 0x200
-#define ZR36057_STILL_TRANS 0x300
-// The datasheet says that STILL_TRANS is 0x140, but the errata says it's 0x300
-
-// which bits of the ZR36057_INTR... mean something special
-#define ZR36057_INTR_GIRQ1 0x40000000
-#define ZR36057_INTR_GIRQ0 0x20000000
-#define ZR36057_INTR_CODREP 0x10000000
-#define ZR36057_INTR_JPEGREP 0x08000000
-#define ZR36057_INTR_ENABLE 0x01000000
+#define BT819Addr 0x8a
+#define BT856Addr 0x88
+#define GID060 0
-// which bits of ZR36057_I2C_BUS mean something special
-#define ZR36057_POST_PEND 0x02000000
-#define ZR36057_POST_TIME 0x01000000
-#define ZR36057_POST_DIR 0x00800000
-
-// function of the Guest CS outputs
-#define ZR36060_GUEST_DATA 0
-#define ZR36060_GUEST_START 1
-#define ZR36060_GUEST_RESET 3
-
-// the still busy bit in ZR36057_STILL_TRANS
-// this assumes we are working in little endian mode
-#define ZR36057_STILL_BUSY 0x80000000
-
-// which bit of ZR36057_I2C_BUS is which
-#define ZR36057_I2C_SCL 1
-#define ZR36057_I2C_SDA 2
-
-// The ZR36060 registers
-#define ZR36060_LOAD 0x000
-#define ZR36060_FIFO_STAT 0x001
-#define ZR36060_INTERFACE 0x002
-#define ZR36060_MODE 0x003
-#define ZR36060_ZERO 0x004
-#define ZR36060_MBCV 0x005
-#define ZR36060_MARKERS_EN 0x006
-#define ZR36060_INT_MASK 0x007
-#define ZR36060_INT_STAT 0x008
-#define ZR36060_TCV_NEThi 0x009
-#define ZR36060_TCV_NETmh 0x00a
-#define ZR36060_TCV_NETml 0x00b
-#define ZR36060_TCV_NETlo 0x00c
-#define ZR36060_TCV_DATAhi 0x00d
-#define ZR36060_TCV_DATAmh 0x00e
-#define ZR36060_TCV_DATAml 0x00f
-#define ZR36060_TCV_DATAlo 0x010
-#define ZR36060_SFhi 0x011
-#define ZR36060_SFlo 0x012
-#define ZR36060_AFhi 0x013
-#define ZR36060_AFme 0x014
-#define ZR36060_AFlo 0x015
-#define ZR36060_ACVhi 0x016
-#define ZR36060_ACVmh 0x017
-#define ZR36060_ACVml 0x018
-#define ZR36060_ACVlo 0x019
-#define ZR36060_ATAhi 0x01a
-#define ZR36060_ATAmh 0x01b
-#define ZR36060_ATAml 0x01c
-#define ZR36060_ATAlo 0x01d
-#define ZR36060_ACV_TRUNhi 0x01e
-#define ZR36060_ACV_TRUNmh 0x01f
-#define ZR36060_ACV_TRUNml 0x020
-#define ZR36060_ACV_TRUNlo 0x021
-#define ZR36060_DEV_ID 0x022
-#define ZR36060_DEV_REV 0x023
-#define ZR36060_TEST_1 0x024
-#define ZR36060_TEST_2 0x025
-#define ZR36060_VCR 0x030
-#define ZR36060_VPR 0x031
-#define ZR36060_SCALE 0x032
-#define ZR36060_BKG_CLR_Y 0x033
-#define ZR36060_BKG_CLR_U 0x034
-#define ZR36060_BKG_CLR_V 0x035
-#define ZR36060_SYNC_VTOTALhi 0x036
-#define ZR36060_SYNC_VTOTALlo 0x037
-#define ZR36060_SYNC_HTOTALhi 0x038
-#define ZR36060_SYNC_HTOTALlo 0x039
-#define ZR36060_SYNC_VSIZE 0x03a
-#define ZR36060_SYNC_HSIZE 0x03b
-#define ZR36060_SYNC_BVSTART 0x03c
-#define ZR36060_SYNC_BHSTART 0x03d
-#define ZR36060_SYNC_BVENDhi 0x03e
-#define ZR36060_SYNC_BVENDlo 0x03f
-#define ZR36060_SYNC_BHENDhi 0x040
-#define ZR36060_SYNC_BHENDlo 0x041
-#define ZR36060_AA_VSTARThi 0x042
-#define ZR36060_AA_VSTARTlo 0x043
-#define ZR36060_AA_VENDhi 0x044
-#define ZR36060_AA_VENDlo 0x045
-#define ZR36060_AA_HSTARThi 0x046
-#define ZR36060_AA_HSTARTlo 0x047
-#define ZR36060_AA_HENDhi 0x048
-#define ZR36060_AA_HENDlo 0x049
-#define ZR36060_SW_VSTARThi 0x04a
-#define ZR36060_SW_VSTARTlo 0x04b
-#define ZR36060_SW_VENDhi 0x04c
-#define ZR36060_SW_VENDlo 0x04d
-#define ZR36060_SW_HSTARThi 0x04e
-#define ZR36060_SW_HSTARTlo 0x04f
-#define ZR36060_SW_HENDhi 0x050
-#define ZR36060_SW_HENDlo 0x051
+#define ZR36057_POST_OFFICE 0x200
+#define ZR36057_POST_PEND 0x02000000
+#define ZR36057_POST_TIME 0x01000000
+#define ZR36057_POST_DIR 0x00800000
#define MB 0x100000
#define NBUF 4
@@ 215,29 94,36 @@ typedef struct {
#define FRAGM_FINAL_B 1
#define STAT_BIT 1
+#define writel(v, a) *(ulong *)(a) = v
+#define writew(v, a) *(ushort *)(a) = v
+#define writeb(v, a) *(uchar *)(a) = v
+#define readl(a) (*(ulong *)(a))
+#define readw(a) (*(ushort *)(a))
+#define readb(a) (*(uchar *)(a))
+
typedef struct MjpgDrv MjpgDrv;
-typedef struct H33_Fragment H33_Fragment;
-typedef struct H33_FragmentTable H33_FragmentTable;
+typedef struct Fragment Fragment;
+typedef struct FragmentTable FragmentTable;
typedef struct CodeData CodeData;
typedef struct ML33Board LML33Board;
#define FRAGSIZE (MB/NBUF)
-struct H33_Fragment {
+struct Fragment {
uchar fragbytes[FRAGSIZE];
};
-struct H33_FragmentTable {
- H33_Fragment * fragmAddress; // Physical address
+struct FragmentTable {
+ Fragment * fragmAddress; // Physical address
ulong fragmLength;
};
struct CodeData {
- char idString[16];
- ulong statCom[4]; // Physical address
- ulong statComInitial[4]; // Physical address
- H33_FragmentTable fragmDescr[4];
- H33_Fragment frag[4];
+ char idString[16];
+ ulong statCom[4]; // Physical address
+ ulong statComInitial[4]; // Physical address
+ FragmentTable fragmDescr[4];
+ Fragment frag[4];
};
extern char static_MjpgDrv_GPL_Notice[];
@@ 249,71 135,14 @@ struct MjpgDrv {
struct wait_queue * intrWaitQ;
};
-#define PCI_DEVICE_ZORAN_36067 PCI_DEVICE_ZORAN_36057
-
-struct ML33Board
-{
- void * pciPhysBaseAddr;
- void * pciBaseAddr;
- Pcidev * pcidev;
-};
-
-extern void * H33Addr;
-extern LML33Board * lml33Board;
+static void * pciPhysBaseAddr;
+static ulong pciBaseAddr;
+static Pcidev * pcidev;
-void LML33Board_ctor(LML33Board*);
-void LML33Board_dtor(LML33Board*);
-int LML33Board_installInterruptHandler(LML33Board*);
-void LML33Board_initHardware(LML33Board*);
void LML33Board_mjpegGo(LML33Board*);
-
-// ZR36067 (PCI controller) register memory access
-ulong LML33Board_readL(LML33Board*,int addr);
-void LML33Board_writeL(LML33Board*,int addr,ulong);
-ushort LML33Board_readW(LML33Board*,int addr);
-void LML33Board_writeW(LML33Board*,int addr,ushort);
-uchar LML33Board_readB(LML33Board*,int addr);
-void LML33Board_writeB(LML33Board*,int addr,uchar);
-int LML33Board_getBit(LML33Board*,int addr,int);
-void LML33Board_setBit(LML33Board*,int addr,int,int);
-
-// I2C (video encoder/decoder) manipulation functions
-void h33_i2c_pause(LML33Board*);
-int h33_i2c_waitscl(LML33Board*);
-void h33_i2c_start(LML33Board*);
-void h33_i2c_stop(LML33Board*);
-void h33_i2c_wrbit(LML33Board*,int bit);
-int h33_i2c_rdbit(LML33Board*);
-int h33_i2c_wrbyte(LML33Board*,int value);
-int h33_i2c_rdbyte(LML33Board*,int* value);
-int h33_i2c_probe(LML33Board*,int addr);
-int h33_i2c_wr8(LML33Board*,int addr, int sub, int value);
-int h33_i2c_rd8(LML33Board*,int addr, int sub, int *value);
-int h33_i2c_bt856rd8 (LML33Board*,int addr, int *msb);
-
-// GPIO access
-void gpioSetDirection(int gpIO,int dir);
-void gpioSet(int gpIO,int value);
-int gpioGet(int gpIO);
-
-// PostOffice access functions
-int h33_post_idle(void);
-int h33_post_write(int guest, int reg, int value);
-int h33_post_read(int guest, int reg);
-
-// ZR36060
-void h33_zr060_write(int reg, int value);
-int h33_zr060_read(int reg);
-
void MjpgDrv_ctor(MjpgDrv*);
void MjpgDrv_dtor(MjpgDrv*);
int MjpgDrv_open(struct inode *iNode, struct file *filePtr);
void MjpgDrv_release(struct inode *iNode, struct file *filePtr);
void MjpgDrv_intrHandler(int irqNo, void *devId, struct pt_regs *ptRegs);
-
-void * static_CodeData_map(ulong h33PHighMemory,ulong h33BufferSize);
-int CodeData_getReadyBuffer(CodeData*);
-int CodeData_getProcessedBuffer(CodeData*this);
-int CodeData_getBuffer(CodeData *,int bufferNo,void** bufferPtr,ushort* frameNo);
-int CodeData_prepareBuffer(CodeData *, int bufferNo);