1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Xilinx AXIS FIFO: interface to the Xilinx AXI-Stream FIFO IP core
4 *
5 * Copyright (C) 2018 Jacob Feder
6 *
7 * Authors: Jacob Feder <jacobsfeder@gmail.com>
8 *
9 * See Xilinx PG080 document for IP details
10 */
11
12 /* ----------------------------
13 * includes
14 * ----------------------------
15 */
16
17 #include <linux/kernel.h>
18 #include <linux/wait.h>
19 #include <linux/spinlock_types.h>
20 #include <linux/device.h>
21 #include <linux/cdev.h>
22 #include <linux/init.h>
23 #include <linux/module.h>
24 #include <linux/slab.h>
25 #include <linux/io.h>
26 #include <linux/moduleparam.h>
27 #include <linux/interrupt.h>
28 #include <linux/param.h>
29 #include <linux/fs.h>
30 #include <linux/device.h>
31 #include <linux/cdev.h>
32 #include <linux/types.h>
33 #include <linux/uaccess.h>
34 #include <linux/jiffies.h>
35
36 #include <linux/of_address.h>
37 #include <linux/of_device.h>
38 #include <linux/of_platform.h>
39
40 /* ----------------------------
41 * driver parameters
42 * ----------------------------
43 */
44
45 #define DRIVER_NAME "axis_fifo"
46
47 #define READ_BUF_SIZE 128U /* read buffer length in words */
48 #define WRITE_BUF_SIZE 128U /* write buffer length in words */
49
50 /* ----------------------------
51 * IP register offsets
52 * ----------------------------
53 */
54
55 #define XLLF_ISR_OFFSET 0x00000000 /* Interrupt Status */
56 #define XLLF_IER_OFFSET 0x00000004 /* Interrupt Enable */
57
58 #define XLLF_TDFR_OFFSET 0x00000008 /* Transmit Reset */
59 #define XLLF_TDFV_OFFSET 0x0000000c /* Transmit Vacancy */
60 #define XLLF_TDFD_OFFSET 0x00000010 /* Transmit Data */
61 #define XLLF_TLR_OFFSET 0x00000014 /* Transmit Length */
62
63 #define XLLF_RDFR_OFFSET 0x00000018 /* Receive Reset */
64 #define XLLF_RDFO_OFFSET 0x0000001c /* Receive Occupancy */
65 #define XLLF_RDFD_OFFSET 0x00000020 /* Receive Data */
66 #define XLLF_RLR_OFFSET 0x00000024 /* Receive Length */
67 #define XLLF_SRR_OFFSET 0x00000028 /* Local Link Reset */
68 #define XLLF_TDR_OFFSET 0x0000002C /* Transmit Destination */
69 #define XLLF_RDR_OFFSET 0x00000030 /* Receive Destination */
70
71 /* ----------------------------
72 * reset register masks
73 * ----------------------------
74 */
75
76 #define XLLF_RDFR_RESET_MASK 0x000000a5 /* receive reset value */
77 #define XLLF_TDFR_RESET_MASK 0x000000a5 /* Transmit reset value */
78 #define XLLF_SRR_RESET_MASK 0x000000a5 /* Local Link reset value */
79
80 /* ----------------------------
81 * interrupt masks
82 * ----------------------------
83 */
84
85 #define XLLF_INT_RPURE_MASK 0x80000000 /* Receive under-read */
86 #define XLLF_INT_RPORE_MASK 0x40000000 /* Receive over-read */
87 #define XLLF_INT_RPUE_MASK 0x20000000 /* Receive underrun (empty) */
88 #define XLLF_INT_TPOE_MASK 0x10000000 /* Transmit overrun */
89 #define XLLF_INT_TC_MASK 0x08000000 /* Transmit complete */
90 #define XLLF_INT_RC_MASK 0x04000000 /* Receive complete */
91 #define XLLF_INT_TSE_MASK 0x02000000 /* Transmit length mismatch */
92 #define XLLF_INT_TRC_MASK 0x01000000 /* Transmit reset complete */
93 #define XLLF_INT_RRC_MASK 0x00800000 /* Receive reset complete */
94 #define XLLF_INT_TFPF_MASK 0x00400000 /* Tx FIFO Programmable Full */
95 #define XLLF_INT_TFPE_MASK 0x00200000 /* Tx FIFO Programmable Empty */
96 #define XLLF_INT_RFPF_MASK 0x00100000 /* Rx FIFO Programmable Full */
97 #define XLLF_INT_RFPE_MASK 0x00080000 /* Rx FIFO Programmable Empty */
98 #define XLLF_INT_ALL_MASK 0xfff80000 /* All the ints */
99 #define XLLF_INT_ERROR_MASK 0xf2000000 /* Error status ints */
100 #define XLLF_INT_RXERROR_MASK 0xe0000000 /* Receive Error status ints */
101 #define XLLF_INT_TXERROR_MASK 0x12000000 /* Transmit Error status ints */
102
103 /* ----------------------------
104 * globals
105 * ----------------------------
106 */
107
108 static struct class *axis_fifo_driver_class; /* char device class */
109
110 static int read_timeout = 1000; /* ms to wait before read() times out */
111 static int write_timeout = 1000; /* ms to wait before write() times out */
112
113 /* ----------------------------
114 * module command-line arguments
115 * ----------------------------
116 */
117
118 module_param(read_timeout, int, 0444);
119 MODULE_PARM_DESC(read_timeout, "ms to wait before blocking read() timing out; set to -1 for no timeout");
120 module_param(write_timeout, int, 0444);
121 MODULE_PARM_DESC(write_timeout, "ms to wait before blocking write() timing out; set to -1 for no timeout");
122
123 /* ----------------------------
124 * types
125 * ----------------------------
126 */
127
128 struct axis_fifo {
129 int irq; /* interrupt */
130 struct resource *mem; /* physical memory */
131 void __iomem *base_addr; /* kernel space memory */
132
133 unsigned int rx_fifo_depth; /* max words in the receive fifo */
134 unsigned int tx_fifo_depth; /* max words in the transmit fifo */
135 int has_rx_fifo; /* whether the IP has the rx fifo enabled */
136 int has_tx_fifo; /* whether the IP has the tx fifo enabled */
137
138 wait_queue_head_t read_queue; /* wait queue for asynchronos read */
139 spinlock_t read_queue_lock; /* lock for reading waitqueue */
140 wait_queue_head_t write_queue; /* wait queue for asynchronos write */
141 spinlock_t write_queue_lock; /* lock for writing waitqueue */
142 unsigned int write_flags; /* write file flags */
143 unsigned int read_flags; /* read file flags */
144
145 struct device *dt_device; /* device created from the device tree */
146 struct device *device; /* device associated with char_device */
147 dev_t devt; /* our char device number */
148 struct cdev char_device; /* our char device */
149 };
150
151 /* ----------------------------
152 * sysfs entries
153 * ----------------------------
154 */
155
sysfs_write(struct device * dev,const char * buf,size_t count,unsigned int addr_offset)156 static ssize_t sysfs_write(struct device *dev, const char *buf,
157 size_t count, unsigned int addr_offset)
158 {
159 struct axis_fifo *fifo = dev_get_drvdata(dev);
160 unsigned long tmp;
161 int rc;
162
163 rc = kstrtoul(buf, 0, &tmp);
164 if (rc < 0)
165 return rc;
166
167 iowrite32(tmp, fifo->base_addr + addr_offset);
168
169 return count;
170 }
171
sysfs_read(struct device * dev,char * buf,unsigned int addr_offset)172 static ssize_t sysfs_read(struct device *dev, char *buf,
173 unsigned int addr_offset)
174 {
175 struct axis_fifo *fifo = dev_get_drvdata(dev);
176 unsigned int read_val;
177 unsigned int len;
178 char tmp[32];
179
180 read_val = ioread32(fifo->base_addr + addr_offset);
181 len = snprintf(tmp, sizeof(tmp), "0x%x\n", read_val);
182 memcpy(buf, tmp, len);
183
184 return len;
185 }
186
isr_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)187 static ssize_t isr_store(struct device *dev, struct device_attribute *attr,
188 const char *buf, size_t count)
189 {
190 return sysfs_write(dev, buf, count, XLLF_ISR_OFFSET);
191 }
192
isr_show(struct device * dev,struct device_attribute * attr,char * buf)193 static ssize_t isr_show(struct device *dev,
194 struct device_attribute *attr, char *buf)
195 {
196 return sysfs_read(dev, buf, XLLF_ISR_OFFSET);
197 }
198
199 static DEVICE_ATTR_RW(isr);
200
ier_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)201 static ssize_t ier_store(struct device *dev, struct device_attribute *attr,
202 const char *buf, size_t count)
203 {
204 return sysfs_write(dev, buf, count, XLLF_IER_OFFSET);
205 }
206
ier_show(struct device * dev,struct device_attribute * attr,char * buf)207 static ssize_t ier_show(struct device *dev,
208 struct device_attribute *attr, char *buf)
209 {
210 return sysfs_read(dev, buf, XLLF_IER_OFFSET);
211 }
212
213 static DEVICE_ATTR_RW(ier);
214
tdfr_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)215 static ssize_t tdfr_store(struct device *dev, struct device_attribute *attr,
216 const char *buf, size_t count)
217 {
218 return sysfs_write(dev, buf, count, XLLF_TDFR_OFFSET);
219 }
220
221 static DEVICE_ATTR_WO(tdfr);
222
tdfv_show(struct device * dev,struct device_attribute * attr,char * buf)223 static ssize_t tdfv_show(struct device *dev,
224 struct device_attribute *attr, char *buf)
225 {
226 return sysfs_read(dev, buf, XLLF_TDFV_OFFSET);
227 }
228
229 static DEVICE_ATTR_RO(tdfv);
230
tdfd_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)231 static ssize_t tdfd_store(struct device *dev, struct device_attribute *attr,
232 const char *buf, size_t count)
233 {
234 return sysfs_write(dev, buf, count, XLLF_TDFD_OFFSET);
235 }
236
237 static DEVICE_ATTR_WO(tdfd);
238
tlr_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)239 static ssize_t tlr_store(struct device *dev, struct device_attribute *attr,
240 const char *buf, size_t count)
241 {
242 return sysfs_write(dev, buf, count, XLLF_TLR_OFFSET);
243 }
244
245 static DEVICE_ATTR_WO(tlr);
246
rdfr_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)247 static ssize_t rdfr_store(struct device *dev, struct device_attribute *attr,
248 const char *buf, size_t count)
249 {
250 return sysfs_write(dev, buf, count, XLLF_RDFR_OFFSET);
251 }
252
253 static DEVICE_ATTR_WO(rdfr);
254
rdfo_show(struct device * dev,struct device_attribute * attr,char * buf)255 static ssize_t rdfo_show(struct device *dev,
256 struct device_attribute *attr, char *buf)
257 {
258 return sysfs_read(dev, buf, XLLF_RDFO_OFFSET);
259 }
260
261 static DEVICE_ATTR_RO(rdfo);
262
rdfd_show(struct device * dev,struct device_attribute * attr,char * buf)263 static ssize_t rdfd_show(struct device *dev,
264 struct device_attribute *attr, char *buf)
265 {
266 return sysfs_read(dev, buf, XLLF_RDFD_OFFSET);
267 }
268
269 static DEVICE_ATTR_RO(rdfd);
270
rlr_show(struct device * dev,struct device_attribute * attr,char * buf)271 static ssize_t rlr_show(struct device *dev,
272 struct device_attribute *attr, char *buf)
273 {
274 return sysfs_read(dev, buf, XLLF_RLR_OFFSET);
275 }
276
277 static DEVICE_ATTR_RO(rlr);
278
srr_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)279 static ssize_t srr_store(struct device *dev, struct device_attribute *attr,
280 const char *buf, size_t count)
281 {
282 return sysfs_write(dev, buf, count, XLLF_SRR_OFFSET);
283 }
284
285 static DEVICE_ATTR_WO(srr);
286
tdr_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)287 static ssize_t tdr_store(struct device *dev, struct device_attribute *attr,
288 const char *buf, size_t count)
289 {
290 return sysfs_write(dev, buf, count, XLLF_TDR_OFFSET);
291 }
292
293 static DEVICE_ATTR_WO(tdr);
294
rdr_show(struct device * dev,struct device_attribute * attr,char * buf)295 static ssize_t rdr_show(struct device *dev,
296 struct device_attribute *attr, char *buf)
297 {
298 return sysfs_read(dev, buf, XLLF_RDR_OFFSET);
299 }
300
301 static DEVICE_ATTR_RO(rdr);
302
303 static struct attribute *axis_fifo_attrs[] = {
304 &dev_attr_isr.attr,
305 &dev_attr_ier.attr,
306 &dev_attr_tdfr.attr,
307 &dev_attr_tdfv.attr,
308 &dev_attr_tdfd.attr,
309 &dev_attr_tlr.attr,
310 &dev_attr_rdfr.attr,
311 &dev_attr_rdfo.attr,
312 &dev_attr_rdfd.attr,
313 &dev_attr_rlr.attr,
314 &dev_attr_srr.attr,
315 &dev_attr_tdr.attr,
316 &dev_attr_rdr.attr,
317 NULL,
318 };
319
320 static const struct attribute_group axis_fifo_attrs_group = {
321 .name = "ip_registers",
322 .attrs = axis_fifo_attrs,
323 };
324
325 /* ----------------------------
326 * implementation
327 * ----------------------------
328 */
329
reset_ip_core(struct axis_fifo * fifo)330 static void reset_ip_core(struct axis_fifo *fifo)
331 {
332 iowrite32(XLLF_SRR_RESET_MASK, fifo->base_addr + XLLF_SRR_OFFSET);
333 iowrite32(XLLF_TDFR_RESET_MASK, fifo->base_addr + XLLF_TDFR_OFFSET);
334 iowrite32(XLLF_RDFR_RESET_MASK, fifo->base_addr + XLLF_RDFR_OFFSET);
335 iowrite32(XLLF_INT_TC_MASK | XLLF_INT_RC_MASK | XLLF_INT_RPURE_MASK |
336 XLLF_INT_RPORE_MASK | XLLF_INT_RPUE_MASK |
337 XLLF_INT_TPOE_MASK | XLLF_INT_TSE_MASK,
338 fifo->base_addr + XLLF_IER_OFFSET);
339 iowrite32(XLLF_INT_ALL_MASK, fifo->base_addr + XLLF_ISR_OFFSET);
340 }
341
342 /* reads a single packet from the fifo as dictated by the tlast signal */
axis_fifo_read(struct file * f,char __user * buf,size_t len,loff_t * off)343 static ssize_t axis_fifo_read(struct file *f, char __user *buf,
344 size_t len, loff_t *off)
345 {
346 struct axis_fifo *fifo = (struct axis_fifo *)f->private_data;
347 size_t bytes_available;
348 unsigned int words_available;
349 unsigned int copied;
350 unsigned int copy;
351 unsigned int i;
352 int ret;
353 u32 tmp_buf[READ_BUF_SIZE];
354
355 if (fifo->read_flags & O_NONBLOCK) {
356 /* opened in non-blocking mode
357 * return if there are no packets available
358 */
359 if (!ioread32(fifo->base_addr + XLLF_RDFO_OFFSET))
360 return -EAGAIN;
361 } else {
362 /* opened in blocking mode
363 * wait for a packet available interrupt (or timeout)
364 * if nothing is currently available
365 */
366 spin_lock_irq(&fifo->read_queue_lock);
367 ret = wait_event_interruptible_lock_irq_timeout(
368 fifo->read_queue,
369 ioread32(fifo->base_addr + XLLF_RDFO_OFFSET),
370 fifo->read_queue_lock,
371 (read_timeout >= 0) ? msecs_to_jiffies(read_timeout) :
372 MAX_SCHEDULE_TIMEOUT);
373 spin_unlock_irq(&fifo->read_queue_lock);
374
375 if (ret == 0) {
376 /* timeout occurred */
377 dev_dbg(fifo->dt_device, "read timeout");
378 return -EAGAIN;
379 } else if (ret == -ERESTARTSYS) {
380 /* signal received */
381 return -ERESTARTSYS;
382 } else if (ret < 0) {
383 dev_err(fifo->dt_device, "wait_event_interruptible_timeout() error in read (ret=%i)\n",
384 ret);
385 return ret;
386 }
387 }
388
389 bytes_available = ioread32(fifo->base_addr + XLLF_RLR_OFFSET);
390 if (!bytes_available) {
391 dev_err(fifo->dt_device, "received a packet of length 0 - fifo core will be reset\n");
392 reset_ip_core(fifo);
393 return -EIO;
394 }
395
396 if (bytes_available > len) {
397 dev_err(fifo->dt_device, "user read buffer too small (available bytes=%zu user buffer bytes=%zu) - fifo core will be reset\n",
398 bytes_available, len);
399 reset_ip_core(fifo);
400 return -EINVAL;
401 }
402
403 if (bytes_available % sizeof(u32)) {
404 /* this probably can't happen unless IP
405 * registers were previously mishandled
406 */
407 dev_err(fifo->dt_device, "received a packet that isn't word-aligned - fifo core will be reset\n");
408 reset_ip_core(fifo);
409 return -EIO;
410 }
411
412 words_available = bytes_available / sizeof(u32);
413
414 /* read data into an intermediate buffer, copying the contents
415 * to userspace when the buffer is full
416 */
417 copied = 0;
418 while (words_available > 0) {
419 copy = min(words_available, READ_BUF_SIZE);
420
421 for (i = 0; i < copy; i++) {
422 tmp_buf[i] = ioread32(fifo->base_addr +
423 XLLF_RDFD_OFFSET);
424 }
425
426 if (copy_to_user(buf + copied * sizeof(u32), tmp_buf,
427 copy * sizeof(u32))) {
428 reset_ip_core(fifo);
429 return -EFAULT;
430 }
431
432 copied += copy;
433 words_available -= copy;
434 }
435
436 return bytes_available;
437 }
438
axis_fifo_write(struct file * f,const char __user * buf,size_t len,loff_t * off)439 static ssize_t axis_fifo_write(struct file *f, const char __user *buf,
440 size_t len, loff_t *off)
441 {
442 struct axis_fifo *fifo = (struct axis_fifo *)f->private_data;
443 unsigned int words_to_write;
444 unsigned int copied;
445 unsigned int copy;
446 unsigned int i;
447 int ret;
448 u32 tmp_buf[WRITE_BUF_SIZE];
449
450 if (len % sizeof(u32)) {
451 dev_err(fifo->dt_device,
452 "tried to send a packet that isn't word-aligned\n");
453 return -EINVAL;
454 }
455
456 words_to_write = len / sizeof(u32);
457
458 if (!words_to_write) {
459 dev_err(fifo->dt_device,
460 "tried to send a packet of length 0\n");
461 return -EINVAL;
462 }
463
464 if (words_to_write > fifo->tx_fifo_depth) {
465 dev_err(fifo->dt_device, "tried to write more words [%u] than slots in the fifo buffer [%u]\n",
466 words_to_write, fifo->tx_fifo_depth);
467 return -EINVAL;
468 }
469
470 if (fifo->write_flags & O_NONBLOCK) {
471 /* opened in non-blocking mode
472 * return if there is not enough room available in the fifo
473 */
474 if (words_to_write > ioread32(fifo->base_addr +
475 XLLF_TDFV_OFFSET)) {
476 return -EAGAIN;
477 }
478 } else {
479 /* opened in blocking mode */
480
481 /* wait for an interrupt (or timeout) if there isn't
482 * currently enough room in the fifo
483 */
484 spin_lock_irq(&fifo->write_queue_lock);
485 ret = wait_event_interruptible_lock_irq_timeout(
486 fifo->write_queue,
487 ioread32(fifo->base_addr + XLLF_TDFV_OFFSET)
488 >= words_to_write,
489 fifo->write_queue_lock,
490 (write_timeout >= 0) ? msecs_to_jiffies(write_timeout) :
491 MAX_SCHEDULE_TIMEOUT);
492 spin_unlock_irq(&fifo->write_queue_lock);
493
494 if (ret == 0) {
495 /* timeout occurred */
496 dev_dbg(fifo->dt_device, "write timeout\n");
497 return -EAGAIN;
498 } else if (ret == -ERESTARTSYS) {
499 /* signal received */
500 return -ERESTARTSYS;
501 } else if (ret < 0) {
502 /* unknown error */
503 dev_err(fifo->dt_device,
504 "wait_event_interruptible_timeout() error in write (ret=%i)\n",
505 ret);
506 return ret;
507 }
508 }
509
510 /* write data from an intermediate buffer into the fifo IP, refilling
511 * the buffer with userspace data as needed
512 */
513 copied = 0;
514 while (words_to_write > 0) {
515 copy = min(words_to_write, WRITE_BUF_SIZE);
516
517 if (copy_from_user(tmp_buf, buf + copied * sizeof(u32),
518 copy * sizeof(u32))) {
519 reset_ip_core(fifo);
520 return -EFAULT;
521 }
522
523 for (i = 0; i < copy; i++)
524 iowrite32(tmp_buf[i], fifo->base_addr +
525 XLLF_TDFD_OFFSET);
526
527 copied += copy;
528 words_to_write -= copy;
529 }
530
531 /* write packet size to fifo */
532 iowrite32(copied * sizeof(u32), fifo->base_addr + XLLF_TLR_OFFSET);
533
534 return (ssize_t)copied * sizeof(u32);
535 }
536
axis_fifo_irq(int irq,void * dw)537 static irqreturn_t axis_fifo_irq(int irq, void *dw)
538 {
539 struct axis_fifo *fifo = (struct axis_fifo *)dw;
540 unsigned int pending_interrupts;
541
542 do {
543 pending_interrupts = ioread32(fifo->base_addr +
544 XLLF_IER_OFFSET) &
545 ioread32(fifo->base_addr
546 + XLLF_ISR_OFFSET);
547 if (pending_interrupts & XLLF_INT_RC_MASK) {
548 /* packet received */
549
550 /* wake the reader process if it is waiting */
551 wake_up(&fifo->read_queue);
552
553 /* clear interrupt */
554 iowrite32(XLLF_INT_RC_MASK & XLLF_INT_ALL_MASK,
555 fifo->base_addr + XLLF_ISR_OFFSET);
556 } else if (pending_interrupts & XLLF_INT_TC_MASK) {
557 /* packet sent */
558
559 /* wake the writer process if it is waiting */
560 wake_up(&fifo->write_queue);
561
562 iowrite32(XLLF_INT_TC_MASK & XLLF_INT_ALL_MASK,
563 fifo->base_addr + XLLF_ISR_OFFSET);
564 } else if (pending_interrupts & XLLF_INT_TFPF_MASK) {
565 /* transmit fifo programmable full */
566
567 iowrite32(XLLF_INT_TFPF_MASK & XLLF_INT_ALL_MASK,
568 fifo->base_addr + XLLF_ISR_OFFSET);
569 } else if (pending_interrupts & XLLF_INT_TFPE_MASK) {
570 /* transmit fifo programmable empty */
571
572 iowrite32(XLLF_INT_TFPE_MASK & XLLF_INT_ALL_MASK,
573 fifo->base_addr + XLLF_ISR_OFFSET);
574 } else if (pending_interrupts & XLLF_INT_RFPF_MASK) {
575 /* receive fifo programmable full */
576
577 iowrite32(XLLF_INT_RFPF_MASK & XLLF_INT_ALL_MASK,
578 fifo->base_addr + XLLF_ISR_OFFSET);
579 } else if (pending_interrupts & XLLF_INT_RFPE_MASK) {
580 /* receive fifo programmable empty */
581
582 iowrite32(XLLF_INT_RFPE_MASK & XLLF_INT_ALL_MASK,
583 fifo->base_addr + XLLF_ISR_OFFSET);
584 } else if (pending_interrupts & XLLF_INT_TRC_MASK) {
585 /* transmit reset complete interrupt */
586
587 iowrite32(XLLF_INT_TRC_MASK & XLLF_INT_ALL_MASK,
588 fifo->base_addr + XLLF_ISR_OFFSET);
589 } else if (pending_interrupts & XLLF_INT_RRC_MASK) {
590 /* receive reset complete interrupt */
591
592 iowrite32(XLLF_INT_RRC_MASK & XLLF_INT_ALL_MASK,
593 fifo->base_addr + XLLF_ISR_OFFSET);
594 } else if (pending_interrupts & XLLF_INT_RPURE_MASK) {
595 /* receive fifo under-read error interrupt */
596 dev_err(fifo->dt_device,
597 "receive under-read interrupt\n");
598
599 iowrite32(XLLF_INT_RPURE_MASK & XLLF_INT_ALL_MASK,
600 fifo->base_addr + XLLF_ISR_OFFSET);
601 } else if (pending_interrupts & XLLF_INT_RPORE_MASK) {
602 /* receive over-read error interrupt */
603 dev_err(fifo->dt_device,
604 "receive over-read interrupt\n");
605
606 iowrite32(XLLF_INT_RPORE_MASK & XLLF_INT_ALL_MASK,
607 fifo->base_addr + XLLF_ISR_OFFSET);
608 } else if (pending_interrupts & XLLF_INT_RPUE_MASK) {
609 /* receive underrun error interrupt */
610 dev_err(fifo->dt_device,
611 "receive underrun error interrupt\n");
612
613 iowrite32(XLLF_INT_RPUE_MASK & XLLF_INT_ALL_MASK,
614 fifo->base_addr + XLLF_ISR_OFFSET);
615 } else if (pending_interrupts & XLLF_INT_TPOE_MASK) {
616 /* transmit overrun error interrupt */
617 dev_err(fifo->dt_device,
618 "transmit overrun error interrupt\n");
619
620 iowrite32(XLLF_INT_TPOE_MASK & XLLF_INT_ALL_MASK,
621 fifo->base_addr + XLLF_ISR_OFFSET);
622 } else if (pending_interrupts & XLLF_INT_TSE_MASK) {
623 /* transmit length mismatch error interrupt */
624 dev_err(fifo->dt_device,
625 "transmit length mismatch error interrupt\n");
626
627 iowrite32(XLLF_INT_TSE_MASK & XLLF_INT_ALL_MASK,
628 fifo->base_addr + XLLF_ISR_OFFSET);
629 } else if (pending_interrupts) {
630 /* unknown interrupt type */
631 dev_err(fifo->dt_device,
632 "unknown interrupt(s) 0x%x\n",
633 pending_interrupts);
634
635 iowrite32(XLLF_INT_ALL_MASK,
636 fifo->base_addr + XLLF_ISR_OFFSET);
637 }
638 } while (pending_interrupts);
639
640 return IRQ_HANDLED;
641 }
642
axis_fifo_open(struct inode * inod,struct file * f)643 static int axis_fifo_open(struct inode *inod, struct file *f)
644 {
645 struct axis_fifo *fifo = (struct axis_fifo *)container_of(inod->i_cdev,
646 struct axis_fifo, char_device);
647 f->private_data = fifo;
648
649 if (((f->f_flags & O_ACCMODE) == O_WRONLY) ||
650 ((f->f_flags & O_ACCMODE) == O_RDWR)) {
651 if (fifo->has_tx_fifo) {
652 fifo->write_flags = f->f_flags;
653 } else {
654 dev_err(fifo->dt_device, "tried to open device for write but the transmit fifo is disabled\n");
655 return -EPERM;
656 }
657 }
658
659 if (((f->f_flags & O_ACCMODE) == O_RDONLY) ||
660 ((f->f_flags & O_ACCMODE) == O_RDWR)) {
661 if (fifo->has_rx_fifo) {
662 fifo->read_flags = f->f_flags;
663 } else {
664 dev_err(fifo->dt_device, "tried to open device for read but the receive fifo is disabled\n");
665 return -EPERM;
666 }
667 }
668
669 return 0;
670 }
671
axis_fifo_close(struct inode * inod,struct file * f)672 static int axis_fifo_close(struct inode *inod, struct file *f)
673 {
674 f->private_data = NULL;
675
676 return 0;
677 }
678
679 static const struct file_operations fops = {
680 .owner = THIS_MODULE,
681 .open = axis_fifo_open,
682 .release = axis_fifo_close,
683 .read = axis_fifo_read,
684 .write = axis_fifo_write
685 };
686
687 /* read named property from the device tree */
get_dts_property(struct axis_fifo * fifo,char * name,unsigned int * var)688 static int get_dts_property(struct axis_fifo *fifo,
689 char *name, unsigned int *var)
690 {
691 int rc;
692
693 rc = of_property_read_u32(fifo->dt_device->of_node, name, var);
694 if (rc) {
695 dev_err(fifo->dt_device, "couldn't read IP dts property '%s'",
696 name);
697 return rc;
698 }
699 dev_dbg(fifo->dt_device, "dts property '%s' = %u\n",
700 name, *var);
701
702 return 0;
703 }
704
axis_fifo_probe(struct platform_device * pdev)705 static int axis_fifo_probe(struct platform_device *pdev)
706 {
707 struct resource *r_irq; /* interrupt resources */
708 struct resource *r_mem; /* IO mem resources */
709 struct device *dev = &pdev->dev; /* OS device (from device tree) */
710 struct axis_fifo *fifo = NULL;
711
712 char device_name[32];
713
714 int rc = 0; /* error return value */
715
716 /* IP properties from device tree */
717 unsigned int rxd_tdata_width;
718 unsigned int txc_tdata_width;
719 unsigned int txd_tdata_width;
720 unsigned int tdest_width;
721 unsigned int tid_width;
722 unsigned int tuser_width;
723 unsigned int data_interface_type;
724 unsigned int has_tdest;
725 unsigned int has_tid;
726 unsigned int has_tkeep;
727 unsigned int has_tstrb;
728 unsigned int has_tuser;
729 unsigned int rx_fifo_depth;
730 unsigned int rx_programmable_empty_threshold;
731 unsigned int rx_programmable_full_threshold;
732 unsigned int axi_id_width;
733 unsigned int axi4_data_width;
734 unsigned int select_xpm;
735 unsigned int tx_fifo_depth;
736 unsigned int tx_programmable_empty_threshold;
737 unsigned int tx_programmable_full_threshold;
738 unsigned int use_rx_cut_through;
739 unsigned int use_rx_data;
740 unsigned int use_tx_control;
741 unsigned int use_tx_cut_through;
742 unsigned int use_tx_data;
743
744 /* ----------------------------
745 * init wrapper device
746 * ----------------------------
747 */
748
749 /* allocate device wrapper memory */
750 fifo = devm_kmalloc(dev, sizeof(*fifo), GFP_KERNEL);
751 if (!fifo)
752 return -ENOMEM;
753
754 dev_set_drvdata(dev, fifo);
755 fifo->dt_device = dev;
756
757 init_waitqueue_head(&fifo->read_queue);
758 init_waitqueue_head(&fifo->write_queue);
759
760 spin_lock_init(&fifo->read_queue_lock);
761 spin_lock_init(&fifo->write_queue_lock);
762
763 /* ----------------------------
764 * init device memory space
765 * ----------------------------
766 */
767
768 /* get iospace for the device */
769 r_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
770 if (!r_mem) {
771 dev_err(fifo->dt_device, "invalid address\n");
772 rc = -ENODEV;
773 goto err_initial;
774 }
775
776 fifo->mem = r_mem;
777
778 /* request physical memory */
779 if (!request_mem_region(fifo->mem->start, resource_size(fifo->mem),
780 DRIVER_NAME)) {
781 dev_err(fifo->dt_device,
782 "couldn't lock memory region at 0x%pa\n",
783 &fifo->mem->start);
784 rc = -EBUSY;
785 goto err_initial;
786 }
787 dev_dbg(fifo->dt_device, "got memory location [0x%pa - 0x%pa]\n",
788 &fifo->mem->start, &fifo->mem->end);
789
790 /* map physical memory to kernel virtual address space */
791 fifo->base_addr = ioremap(fifo->mem->start, resource_size(fifo->mem));
792 if (!fifo->base_addr) {
793 dev_err(fifo->dt_device, "couldn't map physical memory\n");
794 rc = -ENOMEM;
795 goto err_mem;
796 }
797 dev_dbg(fifo->dt_device, "remapped memory to 0x%p\n", fifo->base_addr);
798
799 /* create unique device name */
800 snprintf(device_name, sizeof(device_name), "%s_%pa",
801 DRIVER_NAME, &fifo->mem->start);
802
803 dev_dbg(fifo->dt_device, "device name [%s]\n", device_name);
804
805 /* ----------------------------
806 * init IP
807 * ----------------------------
808 */
809
810 /* retrieve device tree properties */
811 rc = get_dts_property(fifo, "xlnx,axi-str-rxd-tdata-width",
812 &rxd_tdata_width);
813 if (rc)
814 goto err_unmap;
815 rc = get_dts_property(fifo, "xlnx,axi-str-txc-tdata-width",
816 &txc_tdata_width);
817 if (rc)
818 goto err_unmap;
819 rc = get_dts_property(fifo, "xlnx,axi-str-txd-tdata-width",
820 &txd_tdata_width);
821 if (rc)
822 goto err_unmap;
823 rc = get_dts_property(fifo, "xlnx,axis-tdest-width", &tdest_width);
824 if (rc)
825 goto err_unmap;
826 rc = get_dts_property(fifo, "xlnx,axis-tid-width", &tid_width);
827 if (rc)
828 goto err_unmap;
829 rc = get_dts_property(fifo, "xlnx,axis-tuser-width", &tuser_width);
830 if (rc)
831 goto err_unmap;
832 rc = get_dts_property(fifo, "xlnx,data-interface-type",
833 &data_interface_type);
834 if (rc)
835 goto err_unmap;
836 rc = get_dts_property(fifo, "xlnx,has-axis-tdest", &has_tdest);
837 if (rc)
838 goto err_unmap;
839 rc = get_dts_property(fifo, "xlnx,has-axis-tid", &has_tid);
840 if (rc)
841 goto err_unmap;
842 rc = get_dts_property(fifo, "xlnx,has-axis-tkeep", &has_tkeep);
843 if (rc)
844 goto err_unmap;
845 rc = get_dts_property(fifo, "xlnx,has-axis-tstrb", &has_tstrb);
846 if (rc)
847 goto err_unmap;
848 rc = get_dts_property(fifo, "xlnx,has-axis-tuser", &has_tuser);
849 if (rc)
850 goto err_unmap;
851 rc = get_dts_property(fifo, "xlnx,rx-fifo-depth", &rx_fifo_depth);
852 if (rc)
853 goto err_unmap;
854 rc = get_dts_property(fifo, "xlnx,rx-fifo-pe-threshold",
855 &rx_programmable_empty_threshold);
856 if (rc)
857 goto err_unmap;
858 rc = get_dts_property(fifo, "xlnx,rx-fifo-pf-threshold",
859 &rx_programmable_full_threshold);
860 if (rc)
861 goto err_unmap;
862 rc = get_dts_property(fifo, "xlnx,s-axi-id-width", &axi_id_width);
863 if (rc)
864 goto err_unmap;
865 rc = get_dts_property(fifo, "xlnx,s-axi4-data-width", &axi4_data_width);
866 if (rc)
867 goto err_unmap;
868 rc = get_dts_property(fifo, "xlnx,select-xpm", &select_xpm);
869 if (rc)
870 goto err_unmap;
871 rc = get_dts_property(fifo, "xlnx,tx-fifo-depth", &tx_fifo_depth);
872 if (rc)
873 goto err_unmap;
874 rc = get_dts_property(fifo, "xlnx,tx-fifo-pe-threshold",
875 &tx_programmable_empty_threshold);
876 if (rc)
877 goto err_unmap;
878 rc = get_dts_property(fifo, "xlnx,tx-fifo-pf-threshold",
879 &tx_programmable_full_threshold);
880 if (rc)
881 goto err_unmap;
882 rc = get_dts_property(fifo, "xlnx,use-rx-cut-through",
883 &use_rx_cut_through);
884 if (rc)
885 goto err_unmap;
886 rc = get_dts_property(fifo, "xlnx,use-rx-data", &use_rx_data);
887 if (rc)
888 goto err_unmap;
889 rc = get_dts_property(fifo, "xlnx,use-tx-ctrl", &use_tx_control);
890 if (rc)
891 goto err_unmap;
892 rc = get_dts_property(fifo, "xlnx,use-tx-cut-through",
893 &use_tx_cut_through);
894 if (rc)
895 goto err_unmap;
896 rc = get_dts_property(fifo, "xlnx,use-tx-data", &use_tx_data);
897 if (rc)
898 goto err_unmap;
899
900 /* check validity of device tree properties */
901 if (rxd_tdata_width != 32) {
902 dev_err(fifo->dt_device,
903 "rxd_tdata_width width [%u] unsupported\n",
904 rxd_tdata_width);
905 rc = -EIO;
906 goto err_unmap;
907 }
908 if (txd_tdata_width != 32) {
909 dev_err(fifo->dt_device,
910 "txd_tdata_width width [%u] unsupported\n",
911 txd_tdata_width);
912 rc = -EIO;
913 goto err_unmap;
914 }
915 if (has_tdest) {
916 dev_err(fifo->dt_device, "tdest not supported\n");
917 rc = -EIO;
918 goto err_unmap;
919 }
920 if (has_tid) {
921 dev_err(fifo->dt_device, "tid not supported\n");
922 rc = -EIO;
923 goto err_unmap;
924 }
925 if (has_tkeep) {
926 dev_err(fifo->dt_device, "tkeep not supported\n");
927 rc = -EIO;
928 goto err_unmap;
929 }
930 if (has_tstrb) {
931 dev_err(fifo->dt_device, "tstrb not supported\n");
932 rc = -EIO;
933 goto err_unmap;
934 }
935 if (has_tuser) {
936 dev_err(fifo->dt_device, "tuser not supported\n");
937 rc = -EIO;
938 goto err_unmap;
939 }
940 if (use_rx_cut_through) {
941 dev_err(fifo->dt_device, "rx cut-through not supported\n");
942 rc = -EIO;
943 goto err_unmap;
944 }
945 if (use_tx_cut_through) {
946 dev_err(fifo->dt_device, "tx cut-through not supported\n");
947 rc = -EIO;
948 goto err_unmap;
949 }
950 if (use_tx_control) {
951 dev_err(fifo->dt_device, "tx control not supported\n");
952 rc = -EIO;
953 goto err_unmap;
954 }
955
956 /* TODO
957 * these exist in the device tree but it's unclear what they do
958 * - select-xpm
959 * - data-interface-type
960 */
961
962 /* set device wrapper properties based on IP config */
963 fifo->rx_fifo_depth = rx_fifo_depth;
964 /* IP sets TDFV to fifo depth - 4 so we will do the same */
965 fifo->tx_fifo_depth = tx_fifo_depth - 4;
966 fifo->has_rx_fifo = use_rx_data;
967 fifo->has_tx_fifo = use_tx_data;
968
969 reset_ip_core(fifo);
970
971 /* ----------------------------
972 * init device interrupts
973 * ----------------------------
974 */
975
976 /* get IRQ resource */
977 r_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
978 if (!r_irq) {
979 dev_err(fifo->dt_device, "no IRQ found for 0x%pa\n",
980 &fifo->mem->start);
981 rc = -EIO;
982 goto err_unmap;
983 }
984
985 /* request IRQ */
986 fifo->irq = r_irq->start;
987 rc = request_irq(fifo->irq, &axis_fifo_irq, 0, DRIVER_NAME, fifo);
988 if (rc) {
989 dev_err(fifo->dt_device, "couldn't allocate interrupt %i\n",
990 fifo->irq);
991 goto err_unmap;
992 }
993
994 /* ----------------------------
995 * init char device
996 * ----------------------------
997 */
998
999 /* allocate device number */
1000 rc = alloc_chrdev_region(&fifo->devt, 0, 1, DRIVER_NAME);
1001 if (rc < 0)
1002 goto err_irq;
1003 dev_dbg(fifo->dt_device, "allocated device number major %i minor %i\n",
1004 MAJOR(fifo->devt), MINOR(fifo->devt));
1005
1006 /* create driver file */
1007 fifo->device = device_create(axis_fifo_driver_class, NULL, fifo->devt,
1008 NULL, device_name);
1009 if (IS_ERR(fifo->device)) {
1010 dev_err(fifo->dt_device,
1011 "couldn't create driver file\n");
1012 rc = PTR_ERR(fifo->device);
1013 goto err_chrdev_region;
1014 }
1015 dev_set_drvdata(fifo->device, fifo);
1016
1017 /* create character device */
1018 cdev_init(&fifo->char_device, &fops);
1019 rc = cdev_add(&fifo->char_device, fifo->devt, 1);
1020 if (rc < 0) {
1021 dev_err(fifo->dt_device, "couldn't create character device\n");
1022 goto err_dev;
1023 }
1024
1025 /* create sysfs entries */
1026 rc = sysfs_create_group(&fifo->device->kobj, &axis_fifo_attrs_group);
1027 if (rc < 0) {
1028 dev_err(fifo->dt_device, "couldn't register sysfs group\n");
1029 goto err_cdev;
1030 }
1031
1032 dev_info(fifo->dt_device, "axis-fifo created at %pa mapped to 0x%pa, irq=%i, major=%i, minor=%i\n",
1033 &fifo->mem->start, &fifo->base_addr, fifo->irq,
1034 MAJOR(fifo->devt), MINOR(fifo->devt));
1035
1036 return 0;
1037
1038 err_cdev:
1039 cdev_del(&fifo->char_device);
1040 err_dev:
1041 device_destroy(axis_fifo_driver_class, fifo->devt);
1042 err_chrdev_region:
1043 unregister_chrdev_region(fifo->devt, 1);
1044 err_irq:
1045 free_irq(fifo->irq, fifo);
1046 err_unmap:
1047 iounmap(fifo->base_addr);
1048 err_mem:
1049 release_mem_region(fifo->mem->start, resource_size(fifo->mem));
1050 err_initial:
1051 dev_set_drvdata(dev, NULL);
1052 return rc;
1053 }
1054
axis_fifo_remove(struct platform_device * pdev)1055 static int axis_fifo_remove(struct platform_device *pdev)
1056 {
1057 struct device *dev = &pdev->dev;
1058 struct axis_fifo *fifo = dev_get_drvdata(dev);
1059
1060 sysfs_remove_group(&fifo->device->kobj, &axis_fifo_attrs_group);
1061 cdev_del(&fifo->char_device);
1062 dev_set_drvdata(fifo->device, NULL);
1063 device_destroy(axis_fifo_driver_class, fifo->devt);
1064 unregister_chrdev_region(fifo->devt, 1);
1065 free_irq(fifo->irq, fifo);
1066 iounmap(fifo->base_addr);
1067 release_mem_region(fifo->mem->start, resource_size(fifo->mem));
1068 dev_set_drvdata(dev, NULL);
1069 return 0;
1070 }
1071
1072 static const struct of_device_id axis_fifo_of_match[] = {
1073 { .compatible = "xlnx,axi-fifo-mm-s-4.1", },
1074 {},
1075 };
1076 MODULE_DEVICE_TABLE(of, axis_fifo_of_match);
1077
1078 static struct platform_driver axis_fifo_driver = {
1079 .driver = {
1080 .name = DRIVER_NAME,
1081 .of_match_table = axis_fifo_of_match,
1082 },
1083 .probe = axis_fifo_probe,
1084 .remove = axis_fifo_remove,
1085 };
1086
axis_fifo_init(void)1087 static int __init axis_fifo_init(void)
1088 {
1089 pr_info("axis-fifo driver loaded with parameters read_timeout = %i, write_timeout = %i\n",
1090 read_timeout, write_timeout);
1091 axis_fifo_driver_class = class_create(THIS_MODULE, DRIVER_NAME);
1092 return platform_driver_register(&axis_fifo_driver);
1093 }
1094
1095 module_init(axis_fifo_init);
1096
axis_fifo_exit(void)1097 static void __exit axis_fifo_exit(void)
1098 {
1099 platform_driver_unregister(&axis_fifo_driver);
1100 class_destroy(axis_fifo_driver_class);
1101 }
1102
1103 module_exit(axis_fifo_exit);
1104
1105 MODULE_LICENSE("GPL");
1106 MODULE_AUTHOR("Jacob Feder <jacobsfeder@gmail.com>");
1107 MODULE_DESCRIPTION("Xilinx AXI-Stream FIFO v4.1 IP core driver");
1108