]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/zynq/uartzynq.c
merge
[plan9front.git] / sys / src / 9 / zynq / uartzynq.c
1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "io.h"
7
8 enum {
9         CTRL = 0,
10         MODE,
11         IRQEN,
12         IRQDIS,
13         MASK,
14         INTSTAT,
15         RXFIFOLVL = 0x20/4,
16         CHANSTAT = 0x2C/4,
17         FIFO = 0x30/4,
18 };
19
20 enum {
21         TXFULL = 1<<4,
22         TXEMPTY = 1<<3,
23         RXEMPTY = 1<<1,
24         RXTRIG = 1<<0,
25 };
26
27 typedef struct Ctlr {
28         Lock;
29         ulong *r;
30         int irq, iena;
31 } Ctlr;
32
33 Uart* uartenable(Uart *);
34
35 extern PhysUart zynqphysuart;
36
37 static Ctlr zctlr[1] = {
38         {
39                 .r = (void *) VMAP,
40                 .irq = UART1IRQ,
41         }
42 };
43
44 static Uart zuart[1] = {
45         {
46                 .regs = &zctlr[0],
47                 .name = "UART1",
48                 .freq = 25000000,
49                 .phys = &zynqphysuart,
50                 .console = 1,
51                 .baud = 115200,
52         }
53 };
54
55 void
56 uartinit(void)
57 {
58         consuart = zuart;
59 }
60
61 static Uart *
62 zuartpnp(void)
63 {
64         return zuart;
65 }
66
67 static void
68 zuartkick(Uart *uart)
69 {
70         Ctlr *ct;
71         int i;
72
73         if(uart->blocked)
74                 return;
75         ct = uart->regs;
76         for(i = 0; i < 128; i++){
77                 if((ct->r[CHANSTAT] & TXFULL) != 0)
78                         break;
79                 if(uart->op >= uart->oe && uartstageoutput(uart) == 0)
80                         break;
81                 ct->r[FIFO] = *uart->op++;
82         }
83 }
84
85 static void
86 zuartintr(Ureg *, void *arg)
87 {
88         Uart *uart;
89         Ctlr *ct;
90         int c;
91         ulong fl;
92         
93         uart = arg;
94         ct = uart->regs;
95         fl = ct->r[INTSTAT] & ct->r[MASK];
96         ct->r[INTSTAT] = fl;
97         if((fl & RXTRIG) != 0)
98                 while((ct->r[CHANSTAT] & RXEMPTY) == 0){
99                         c = ct->r[FIFO];
100                         uartrecv(uart, c);
101                 }
102         if((fl & TXEMPTY) != 0)
103                 zuartkick(uart);
104 }
105
106 static void
107 zuartenable(Uart *uart, int ie)
108 {
109         Ctlr *ctlr;
110         
111         ctlr = uart->regs;
112         ilock(ctlr);
113         while((ctlr->r[CHANSTAT] & TXEMPTY) == 0)
114                 ;
115         ctlr->r[IRQDIS] = -1;
116         ctlr->r[RXFIFOLVL] = 1;
117         if(ie){
118                 if(!ctlr->iena){
119                         intrenable(ctlr->irq, zuartintr, uart, LEVEL, uart->name);
120                         ctlr->iena = 1;
121                 }
122                 ctlr->r[IRQEN] = RXTRIG | TXEMPTY;
123         }
124         iunlock(ctlr);
125 }
126
127 static int
128 zuartgetc(Uart *uart)
129 {
130         Ctlr *c;
131         
132         c = uart->regs;
133         while((c->r[CHANSTAT] & RXEMPTY) != 0)
134                 ;
135         return c->r[FIFO];
136 }
137
138 static void
139 zuartputc(Uart *uart, int c)
140 {
141         Ctlr *ct;
142         
143         ct = uart->regs;
144         while((ct->r[CHANSTAT] & TXFULL) != 0)
145                 ;
146         ct->r[FIFO] = c;
147         return;
148 }
149
150 int
151 uartconsole(void)
152 {
153         Uart *uart = zuart;
154
155         if(up == nil)
156                 return -1;
157
158         if(uartenable(uart) != nil){
159                 serialoq = uart->oq;
160                 uart->opens++;
161                 consuart = uart;
162         }
163         return 0;
164 }
165
166 int
167 zuartbits(Uart *uart, int n)
168 {
169         Ctlr *ct;
170         
171         ct = uart->regs;
172         ct->r[MODE] &= ~6;
173         switch(n){
174         case 8:
175                 return 0;
176         case 7:
177                 ct->r[MODE] |= 4;
178                 return 0;
179         case 6:
180                 ct->r[MODE] |= 6;
181                 return 0;
182         default:
183                 return -1;
184         }
185 }
186
187 int
188 zuartbaud(Uart *, int n)
189 {
190         print("uart baud %d\n", n);
191         return 0;
192 }
193
194 int
195 zuartparity(Uart *uart, int p)
196 {
197         Ctlr *ct;
198         
199         ct = uart->regs;
200         switch(p){
201         case 'o':
202                 ct->r[MODE] = ct->r[MODE] & ~0x38 | 0x08;
203                 return 0;
204         case 'e':
205                 ct->r[MODE] = ct->r[MODE] & ~0x38;
206                 return 0;
207         case 'n':
208                 ct->r[MODE] = ct->r[MODE] & 0x38 | 0x20;
209                 return 0;
210         default:
211                 return -1;
212         }
213 }
214
215 void
216 zuartnop(Uart *, int)
217 {
218 }
219
220 int
221 zuartnope(Uart *, int)
222 {
223         return -1;
224 }
225
226
227 PhysUart zynqphysuart = {
228         .pnp = zuartpnp,
229         .enable = zuartenable,
230         .kick = zuartkick,
231         .getc = zuartgetc,
232         .putc = zuartputc,
233         .bits = zuartbits,
234         .baud = zuartbaud,
235         .parity = zuartparity,
236         
237         .stop = zuartnope,
238         .rts = zuartnop,
239         .dtr = zuartnop,
240         .dobreak = zuartnop,
241         .fifo = zuartnop,
242         .power = zuartnop,
243         .modemctl = zuartnop,
244 };