summaryrefslogtreecommitdiff
path: root/os/ipengine/devfpga.c
diff options
context:
space:
mode:
authorKonstantin Kirik (snegovick) <snegovick@uprojects.org>2025-12-28 12:27:31 +0300
committerKonstantin Kirik (snegovick) <snegovick@uprojects.org>2025-12-28 12:27:31 +0300
commit78ee7d5717807e6ac779293d0d3c78341de6130a (patch)
treea43e3b0f61318ac45e6d907c7cc5bad2c6d7f497 /os/ipengine/devfpga.c
parentbdaf46cf45bbb59261da245d548a179d95a42768 (diff)
Move existing boards into subdits split per arch
Diffstat (limited to 'os/ipengine/devfpga.c')
-rw-r--r--os/ipengine/devfpga.c389
1 files changed, 0 insertions, 389 deletions
diff --git a/os/ipengine/devfpga.c b/os/ipengine/devfpga.c
deleted file mode 100644
index 41d1a445..00000000
--- a/os/ipengine/devfpga.c
+++ /dev/null
@@ -1,389 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-
-#include "io.h"
-#include "archipe.h"
-
-enum {
- FPGASIZE = 8*1024*1024,
- FPGATMR = 2-1, /* BCLK timer number (mapped to origin 0) */
- TIMERSH = FPGATMR*4, /* timer field shift */
-
- COM3= IBIT(1)|IBIT(2), /* sccr: clock output disabled */
-
- ConfDone = 1<<1,
- nStatus = 1<<0,
-};
-
-/*
- * provisional FPGA interface for simple development work;
- * for more complex things, use this to load the device then have a
- * purpose-built device driver or module
- */
-
-enum{
- Qdir,
- Qmemb,
- Qmemw,
- Qprog,
- Qctl,
- Qclk,
- Qstatus,
-};
-
-static struct {
- QLock;
- int clkspeed;
-} fpga;
-
-static void resetfpga(void);
-static void startfpga(int);
-static int endfpga(void);
-static int fpgastatus(void);
-static void powerfpga(int);
-static void vclkenable(int);
-static void vclkset(char*, char*, char*, char*);
-static void memmovew(ushort*, ushort*, long);
-
-static Dirtab fpgadir[]={
- ".", {Qdir, 0, QTDIR}, 0, 0555,
- "fpgamemb", {Qmemb, 0}, FPGASIZE, 0666,
- "fpgamemw", {Qmemw, 0}, FPGASIZE, 0666,
- "fpgaprog", {Qprog, 0}, 0, 0222,
- "fpgastatus", {Qstatus, 0}, 0, 0444,
- "fpgactl", {Qctl, 0}, 0, 0666,
- "fpgaclk", {Qclk, 0}, 0, 0666,
-};
-
-static char Eodd[] = "odd count or offset";
-
-static void
-fpgareset(void)
-{
- powerfpga(0);
-}
-
-static Chan*
-fpgaattach(char *spec)
-{
- return devattach('G', spec);
-}
-
-static Walkqid*
-fpgawalk(Chan *c, Chan *nc, char **name, int nname)
-{
- return devwalk(c, nc, name, nname, fpgadir, nelem(fpgadir), devgen);
-}
-
-static int
-fpgastat(Chan *c, uchar *dp, int n)
-{
- return devstat(c, dp, n, fpgadir, nelem(fpgadir), devgen);
-}
-
-static Chan*
-fpgaopen(Chan *c, int omode)
-{
- return devopen(c, omode, fpgadir, nelem(fpgadir), devgen);
-}
-
-static void
-fpgaclose(Chan*)
-{
-}
-
-static long
-fpgaread(Chan *c, void *buf, long n, vlong offset)
-{
- int v;
- char stat[32], *p;
-
- if(c->qid.type & QTDIR)
- return devdirread(c, buf, n, fpgadir, nelem(fpgadir), devgen);
-
- switch((ulong)c->qid.path){
- case Qmemb:
- if(offset >= FPGASIZE)
- return 0;
- if(offset+n >= FPGASIZE)
- n = FPGASIZE-offset;
- memmove(buf, KADDR(FPGAMEM+offset), n);
- return n;
- case Qmemw:
- if((n | offset) & 1)
- error(Eodd);
- if(offset >= FPGASIZE)
- return 0;
- if(offset+n >= FPGASIZE)
- n = FPGASIZE-offset;
- memmovew((ushort*)buf, (ushort*)KADDR(FPGAMEM+offset), n);
- return n;
- case Qstatus:
- v = fpgastatus();
- p = seprint(stat, stat+sizeof(stat), "%sconfig", v&ConfDone?"":"!");
- seprint(p, stat+sizeof(stat), " %sstatus\n", v&nStatus?"":"!");
- return readstr(offset, buf, n, stat);
- case Qclk:
- return readnum(offset, buf, n, fpga.clkspeed, NUMSIZE);
- case Qctl:
- case Qprog:
- return 0;
- }
- error(Egreg);
- return 0; /* not reached */
-}
-
-static long
-fpgawrite(Chan *c, void *buf, long n, vlong offset)
-{
- int i, j, v;
- ulong w;
- Cmdbuf *cb;
- ulong *cfg;
- uchar *cp;
-
- switch((ulong)c->qid.path){
- case Qmemb:
- if(offset >= FPGASIZE)
- return 0;
- if(offset+n >= FPGASIZE)
- n = FPGASIZE-offset;
- memmove(KADDR(FPGAMEM+offset), buf, n);
- return n;
- case Qmemw:
- if((n | offset) & 1)
- error(Eodd);
- if(offset >= FPGASIZE)
- return 0;
- if(offset+n >= FPGASIZE)
- n = FPGASIZE-offset;
- memmovew((ushort*)KADDR(FPGAMEM+offset), (ushort*)buf, n);
- return n;
- case Qctl:
- cb = parsecmd(buf, n);
- if(waserror()){
- free(cb);
- nexterror();
- }
- if(cb->nf < 1)
- error(Ebadarg);
- if(strcmp(cb->f[0], "reset") == 0)
- resetfpga();
- else if(strcmp(cb->f[0], "bclk") == 0){
- v = 48;
- if(cb->nf > 1)
- v = strtoul(cb->f[1], nil, 0);
- if(v <= 0 || 48%v != 0)
- error(Ebadarg);
- startfpga(48/v-1);
- }else if(strcmp(cb->f[0], "vclk") == 0){
- if(cb->nf == 5){ /* vclk n m v r */
- vclkenable(1);
- vclkset(cb->f[1], cb->f[2], cb->f[3], cb->f[4]);
- }else
- vclkenable(cb->nf < 2 || strcmp(cb->f[1], "on") == 0);
- }else if(strcmp(cb->f[0], "power") == 0)
- powerfpga(cb->nf < 2 || strcmp(cb->f[1], "off") != 0);
- else
- error(Ebadarg);
- poperror();
- free(cb);
- return n;
- case Qprog:
- qlock(&fpga);
- if(waserror()){
- qunlock(&fpga);
- nexterror();
- }
- powerfpga(1);
- resetfpga();
- cfg = KADDR(FPGACR);
- cp = buf;
- for(i=0; i<n; i++){
- w = cp[i];
- for(j=0; j<8; j++){
- *cfg = w&1;
- w >>= 1;
- }
- }
- for(j=0; j<50; j++) /* Altera note says at least 10 clock cycles, but microblaster uses 50 */
- *cfg = 0;
- v = fpgastatus();
- if(v != (nStatus|ConfDone)){
- snprint(up->genbuf, sizeof(up->genbuf), "error loading fpga: status %d", v);
- error(up->genbuf);
- }
- poperror();
- qunlock(&fpga);
- return n;
- }
- error(Egreg);
- return 0; /* not reached */
-}
-
-/*
- * PDN seems to control power to the FPGA subsystem
- * but it is not documented nor is its scope clear (PLL as well?).
- * It will not run without it.
- */
-static void
-powerfpga(int on)
-{
- IMM *io;
-
- io = ioplock();
- if(io->sccr & COM3){
- io->sccrk = KEEP_ALIVE_KEY;
- io->sccr &= ~ COM3; /* FPGA designs can use the clock */
- io->sccrk = ~KEEP_ALIVE_KEY;
- }
- io->pcpar &= ~PDN;
- io->pcdir |= PDN;
- if(on)
- io->pcdat &= ~PDN;
- else
- io->pcdat |= PDN;
- iopunlock();
-}
-
-static void
-resetfpga(void)
-{
- IMM *io;
-
- io = ioplock();
- io->pcpar &= ~nCONFIG;
- io->pcdir |= nCONFIG;
- io->pcdat &= ~nCONFIG;
- microdelay(200);
- io->pcdat |= nCONFIG;
- iopunlock();
-}
-
-static int
-fpgastatus(void)
-{
- /* isolate status bits IP_B0 and IP_B1 */
- return (m->iomem->pipr>>14) & (ConfDone|nStatus);
-}
-
-static void
-startfpga(int scale)
-{
- IMM *io;
-
- io = ioplock();
- io->tgcr &= ~(0xF<<TIMERSH);
- io->tmr2 = ((scale&0xFF)<<8) | 0x2A;
- io->tcn2 = 0;
- io->trr2 = 0;
- io->ter2 = 0xFFFF;
- io->tgcr |= 0x1<<TIMERSH;
- io->padir |= BCLK;
- io->papar |= BCLK;
- iopunlock();
-}
-
-static void
-vclkenable(int i)
-{
- IMM *io;
-
- io = ioplock();
- io->padir &= ~VCLK;
- io->papar &= ~VCLK;
- io->pbdir |= EnableVCLK;
- io->pbpar &= ~EnableVCLK;
- if(i)
- io->pbdat |= EnableVCLK;
- else
- io->pbdat &= ~EnableVCLK;
- iopunlock();
-}
-
-static void
-vclkin(ulong *clk, int v)
-{
- int i;
-
- for(i=0; i<7; i++)
- *clk = (v>>i) & 1;
-}
-
-static void
-vclkset(char *ns, char *ms, char *vs, char *rs)
-{
- int n, m, v, r;
- ulong *clk;
-
- clk = KADDR(CLOCKCR);
- n = strtol(ns, nil, 0);
- m = strtol(ms, nil, 0);
- v = strtol(vs, nil, 0);
- r = strtol(rs, nil, 0);
- if(n < 3 || n > 127 || m < 3 || m > 127 || v != 1 && v != 8 ||
- r != 1 && r != 2 && r != 4 && r != 8)
- error(Ebadarg);
- vclkenable(0);
- vclkin(clk, n);
- vclkin(clk, m);
- *clk = (v==0) & 1;
- *clk = 1; *clk = 1;
- *clk = r == 2 || r == 8;
- *clk = r == 4 || r == 8;
- *clk = 1; /* clock out */
- *clk = 0; /* disable clk/x */
- *clk = 1; *clk = 0; *clk = 1;
- *clk = 0; *clk = 0; *clk = 0;
- vclkenable(1);
-}
-
-/*
- * copy data aligned on 16-bit word boundaries.
- */
-static void
-memmovew(ushort *to, ushort *from, long count)
-{
- int n;
-
- if(count <= 0)
- return;
- count >>= 1;
- n = (count+7) >> 3;
- switch(count&7) { /* Duff's device */
- case 0: do { *to++ = *from++;
- case 7: *to++ = *from++;
- case 6: *to++ = *from++;
- case 5: *to++ = *from++;
- case 4: *to++ = *from++;
- case 3: *to++ = *from++;
- case 2: *to++ = *from++;
- case 1: *to++ = *from++;
- } while(--n > 0);
- }
-}
-
-Dev fpgadevtab = {
- 'G',
- "fpga",
-
- fpgareset,
- devinit,
- devshutdown,
- fpgaattach,
- fpgawalk,
- fpgastat,
- fpgaopen,
- devcreate,
- fpgaclose,
- fpgaread,
- devbread,
- fpgawrite,
- devbwrite,
- devremove,
- devwstat,
-};