2 #include "../port/lib.h"
8 #include "../port/error.h"
20 static Dirtab archdir[Qmax] = {
21 ".", { Qdir, 0, QTDIR }, 0, 0555,
22 "temp", { Qtemp, 0}, 0, 0440,
23 "pl", { Qpl, 0 }, 0, 0660,
24 "fbctl", { Qfbctl, 0 }, 0, 0660,
26 static int narchdir = Qbase;
28 static int temp = -128;
31 enum { PLBUFSIZ = 8192 };
33 static Rendez plinitr, pldoner, pldmar;
34 static QLock plrlock, plwlock;
55 FPGA0_CLK_CTRL = 0x170/4,
70 slcr[0x100/4] |= 1<<4;
71 slcr[0x104/4] |= 1<<4;
72 slcr[0x108/4] |= 1<<4;
73 slcr[DEVCTRL] &= ~PROG;
74 slcr[0x244/4] = 1<<4|1<<5;
78 xadcirq(Ureg *, void *)
81 static int al, notfirst;
83 while((devc[XADCMSTS] & 1<<8) == 0){
84 v = ((u16int)devc[XADCREAD]) >> 4;
87 print("temperature sensor reads 0, shouldn't happen\n");
91 temp = v * 5040 / 4096 - 2732;
94 print("temperature exceeds 80 deg C\n");
100 print("chip temperature exceeds 90 deg C, shutting down");
110 devc[XADCCMD] = 1<<26 | 0<<16;
119 devc = vmap(DEVC_BASE, 0x11C);
120 devc[XADCMCTL] |= 1<<4;
121 devc[XADCMCTL] &= ~(1<<4);
122 devc[XADCCMD] = 0x08030000;
123 for(i = 0; i < 15; i++)
125 while((devc[XADCMSTS] & 1<<10) == 0)
127 while((devc[XADCMSTS] & 1<<8) == 0){
131 devc[XADCCFG] = 0x80001114;
132 devc[XADCMASK] = ~(1<<8);
134 intrenable(XADCIRQ, xadcirq, nil, LEVEL, "xadc");
135 addclock0link(xadctimer, XADCINTERVAL);
141 return devc[DEVSTS] & INIT;
147 return devc[DEVISTS] & DONE;
157 plirq(Ureg *, void *)
162 if((fl & INITPE) != 0)
164 if((fl & DONE) != 0){
167 devc[DEVMASK] |= DONE;
168 axi->attr &= ~SG_FAULT;
171 if((fl & DMADONE) != 0){
183 memset(&seg, 0, sizeof seg);
184 seg.attr = SG_PHYSICAL | SG_DEVICE | SG_NOEXEC | SG_FAULT;
187 seg.size = 0x8000000;
188 axi = addphysseg(&seg);
190 devc[DEVCTRL] &= ~(PROG|1<<25);
191 devc[DEVCTRL] |= 3<<26|PROG;
193 devc[DEVMASK] = ~(DONE|INITPE|DMADONE);
194 intrenable(DEVCIRQ, plirq, nil, LEVEL, "pl");
196 slcr[FPGA0_CLK_CTRL] = 1<<20 | 10<<8;
202 axi->attr |= SG_FAULT;
208 devc[DEVISTS] = DONE|INITPE|DMADONE;
209 devc[DEVCTRL] |= PROG;
210 devc[DEVCTRL] &= ~PROG;
211 devc[DEVMASK] &= ~DONE;
212 devc[DEVCTRL] |= PROG;
216 sleep(&plinitr, isplinit, nil);
221 plwrite(uintptr pa, long n)
227 devc[DMASRCL] = n>>2;
232 sleep(&pldmar, isdmadone, nil);
239 plcopy(uchar *d, long n)
245 if((n & 3) != 0 || n <= 0)
261 memmove(plbuf, d, nn);
262 cleandse(plbuf, plbuf + nn);
263 clean2pa(pa, pa + nn);
264 n -= plwrite(pa, nn);
282 archread(Chan *c, void *a, long n, vlong offset)
286 switch((ulong)c->qid.path){
288 return devdirread(c, a, n, archdir, narchdir, devgen);
290 snprint(buf, sizeof(buf), "%d.%d\n", temp/10, temp%10);
291 return readstr(offset, a, n, buf);
298 sleep(&pldoner, ispldone, nil);
303 return fbctlread(c, a, n, offset);
311 archwrite(Chan *c, void *a, long n, vlong offset)
313 switch((ulong)c->qid.path){
317 return fbctlwrite(c, a, n, offset);
325 archwalk(Chan* c, Chan *nc, char** name, int nname)
327 return devwalk(c, nc, name, nname, archdir, narchdir, devgen);
331 archstat(Chan* c, uchar* dp, int n)
333 return devstat(c, dp, n, archdir, narchdir, devgen);
337 archopen(Chan* c, int omode)
339 devopen(c, omode, archdir, narchdir, devgen);
340 if((ulong)c->qid.path == Qpl && (c->mode == OWRITE || c->mode == ORDWR)){
341 if(incref(&plwopen) != 1){
346 plbuf = smalloc(PLBUFSIZ);
355 if((c->flag & COPEN) != 0)
356 if((ulong)c->qid.path == Qpl && (c->mode == OWRITE || c->mode == ORDWR)){
364 archattach(char* spec)
366 return devattach('P', spec);