Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
mpc52xx_lpbfifo.c
Go to the documentation of this file.
1 /*
2  * LocalPlus Bus FIFO driver for the Freescale MPC52xx.
3  *
4  * Copyright (C) 2009 Secret Lab Technologies Ltd.
5  *
6  * This file is released under the GPLv2
7  *
8  * Todo:
9  * - Add support for multiple requests to be queued.
10  */
11 
12 #include <linux/interrupt.h>
13 #include <linux/kernel.h>
14 #include <linux/of.h>
15 #include <linux/of_platform.h>
16 #include <linux/spinlock.h>
17 #include <linux/module.h>
18 #include <asm/io.h>
19 #include <asm/prom.h>
20 #include <asm/mpc52xx.h>
21 #include <asm/time.h>
22 
25 #include <sysdev/bestcomm/gen_bd.h>
26 
27 MODULE_AUTHOR("Grant Likely <[email protected]>");
28 MODULE_DESCRIPTION("MPC5200 LocalPlus FIFO device driver");
29 MODULE_LICENSE("GPL");
30 
31 #define LPBFIFO_REG_PACKET_SIZE (0x00)
32 #define LPBFIFO_REG_START_ADDRESS (0x04)
33 #define LPBFIFO_REG_CONTROL (0x08)
34 #define LPBFIFO_REG_ENABLE (0x0C)
35 #define LPBFIFO_REG_BYTES_DONE_STATUS (0x14)
36 #define LPBFIFO_REG_FIFO_DATA (0x40)
37 #define LPBFIFO_REG_FIFO_STATUS (0x44)
38 #define LPBFIFO_REG_FIFO_CONTROL (0x48)
39 #define LPBFIFO_REG_FIFO_ALARM (0x4C)
40 
42  struct device *dev;
44  void __iomem *regs;
45  int irq;
47 
51 
52  /* Current state data */
55 };
56 
57 /* The MPC5200 has only one fifo, so only need one instance structure */
58 static struct mpc52xx_lpbfifo lpbfifo;
59 
63 static void mpc52xx_lpbfifo_kick(struct mpc52xx_lpbfifo_request *req)
64 {
65  size_t transfer_size = req->size - req->pos;
66  struct bcom_bd *bd;
67  void __iomem *reg;
68  u32 *data;
69  int i;
70  int bit_fields;
71  int dma = !(req->flags & MPC52XX_LPBFIFO_FLAG_NO_DMA);
73  int poll_dma = req->flags & MPC52XX_LPBFIFO_FLAG_POLL_DMA;
74 
75  /* Set and clear the reset bits; is good practice in User Manual */
76  out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
77 
78  /* set master enable bit */
79  out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x00000001);
80  if (!dma) {
81  /* While the FIFO can be setup for transfer sizes as large as
82  * 16M-1, the FIFO itself is only 512 bytes deep and it does
83  * not generate interrupts for FIFO full events (only transfer
84  * complete will raise an IRQ). Therefore when not using
85  * Bestcomm to drive the FIFO it needs to either be polled, or
86  * transfers need to constrained to the size of the fifo.
87  *
88  * This driver restricts the size of the transfer
89  */
90  if (transfer_size > 512)
91  transfer_size = 512;
92 
93  /* Load the FIFO with data */
94  if (write) {
95  reg = lpbfifo.regs + LPBFIFO_REG_FIFO_DATA;
96  data = req->data + req->pos;
97  for (i = 0; i < transfer_size; i += 4)
98  out_be32(reg, *data++);
99  }
100 
101  /* Unmask both error and completion irqs */
102  out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x00000301);
103  } else {
104  /* Choose the correct direction
105  *
106  * Configure the watermarks so DMA will always complete correctly.
107  * It may be worth experimenting with the ALARM value to see if
108  * there is a performance impacit. However, if it is wrong there
109  * is a risk of DMA not transferring the last chunk of data
110  */
111  if (write) {
112  out_be32(lpbfifo.regs + LPBFIFO_REG_FIFO_ALARM, 0x1e4);
113  out_8(lpbfifo.regs + LPBFIFO_REG_FIFO_CONTROL, 7);
114  lpbfifo.bcom_cur_task = lpbfifo.bcom_tx_task;
115  } else {
116  out_be32(lpbfifo.regs + LPBFIFO_REG_FIFO_ALARM, 0x1ff);
117  out_8(lpbfifo.regs + LPBFIFO_REG_FIFO_CONTROL, 0);
118  lpbfifo.bcom_cur_task = lpbfifo.bcom_rx_task;
119 
120  if (poll_dma) {
121  if (lpbfifo.dma_irqs_enabled) {
122  disable_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task));
123  lpbfifo.dma_irqs_enabled = 0;
124  }
125  } else {
126  if (!lpbfifo.dma_irqs_enabled) {
127  enable_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task));
128  lpbfifo.dma_irqs_enabled = 1;
129  }
130  }
131  }
132 
133  bd = bcom_prepare_next_buffer(lpbfifo.bcom_cur_task);
134  bd->status = transfer_size;
135  if (!write) {
136  /*
137  * In the DMA read case, the DMA doesn't complete,
138  * possibly due to incorrect watermarks in the ALARM
139  * and CONTROL regs. For now instead of trying to
140  * determine the right watermarks that will make this
141  * work, just increase the number of bytes the FIFO is
142  * expecting.
143  *
144  * When submitting another operation, the FIFO will get
145  * reset, so the condition of the FIFO waiting for a
146  * non-existent 4 bytes will get cleared.
147  */
148  transfer_size += 4; /* BLECH! */
149  }
150  bd->data[0] = req->data_phys + req->pos;
151  bcom_submit_next_buffer(lpbfifo.bcom_cur_task, NULL);
152 
153  /* error irq & master enabled bit */
154  bit_fields = 0x00000201;
155 
156  /* Unmask irqs */
157  if (write && (!poll_dma))
158  bit_fields |= 0x00000100; /* completion irq too */
159  out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, bit_fields);
160  }
161 
162  /* Set transfer size, width, chip select and READ mode */
163  out_be32(lpbfifo.regs + LPBFIFO_REG_START_ADDRESS,
164  req->offset + req->pos);
165  out_be32(lpbfifo.regs + LPBFIFO_REG_PACKET_SIZE, transfer_size);
166 
167  bit_fields = req->cs << 24 | 0x000008;
168  if (!write)
169  bit_fields |= 0x010000; /* read mode */
170  out_be32(lpbfifo.regs + LPBFIFO_REG_CONTROL, bit_fields);
171 
172  /* Kick it off */
173  if (!lpbfifo.req->defer_xfer_start)
174  out_8(lpbfifo.regs + LPBFIFO_REG_PACKET_SIZE, 0x01);
175  if (dma)
176  bcom_enable(lpbfifo.bcom_cur_task);
177 }
178 
220 static irqreturn_t mpc52xx_lpbfifo_irq(int irq, void *dev_id)
221 {
223  u32 status = in_8(lpbfifo.regs + LPBFIFO_REG_BYTES_DONE_STATUS);
224  void __iomem *reg;
225  u32 *data;
226  int count, i;
227  int do_callback = 0;
228  u32 ts;
229  unsigned long flags;
230  int dma, write, poll_dma;
231 
232  spin_lock_irqsave(&lpbfifo.lock, flags);
233  ts = get_tbl();
234 
235  req = lpbfifo.req;
236  if (!req) {
237  spin_unlock_irqrestore(&lpbfifo.lock, flags);
238  pr_err("bogus LPBFIFO IRQ\n");
239  return IRQ_HANDLED;
240  }
241 
242  dma = !(req->flags & MPC52XX_LPBFIFO_FLAG_NO_DMA);
243  write = req->flags & MPC52XX_LPBFIFO_FLAG_WRITE;
244  poll_dma = req->flags & MPC52XX_LPBFIFO_FLAG_POLL_DMA;
245 
246  if (dma && !write) {
247  spin_unlock_irqrestore(&lpbfifo.lock, flags);
248  pr_err("bogus LPBFIFO IRQ (dma and not writting)\n");
249  return IRQ_HANDLED;
250  }
251 
252  if ((status & 0x01) == 0) {
253  goto out;
254  }
255 
256  /* check abort bit */
257  if (status & 0x10) {
258  out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
259  do_callback = 1;
260  goto out;
261  }
262 
263  /* Read result from hardware */
264  count = in_be32(lpbfifo.regs + LPBFIFO_REG_BYTES_DONE_STATUS);
265  count &= 0x00ffffff;
266 
267  if (!dma && !write) {
268  /* copy the data out of the FIFO */
269  reg = lpbfifo.regs + LPBFIFO_REG_FIFO_DATA;
270  data = req->data + req->pos;
271  for (i = 0; i < count; i += 4)
272  *data++ = in_be32(reg);
273  }
274 
275  /* Update transfer position and count */
276  req->pos += count;
277 
278  /* Decide what to do next */
279  if (req->size - req->pos)
280  mpc52xx_lpbfifo_kick(req); /* more work to do */
281  else
282  do_callback = 1;
283 
284  out:
285  /* Clear the IRQ */
286  out_8(lpbfifo.regs + LPBFIFO_REG_BYTES_DONE_STATUS, 0x01);
287 
288  if (dma && (status & 0x11)) {
289  /*
290  * Count the DMA as complete only when the FIFO completion
291  * status or abort bits are set.
292  *
293  * (status & 0x01) should always be the case except sometimes
294  * when using polled DMA.
295  *
296  * (status & 0x10) {transfer aborted}: This case needs more
297  * testing.
298  */
299  bcom_retrieve_buffer(lpbfifo.bcom_cur_task, &status, NULL);
300  }
301  req->last_byte = ((u8 *)req->data)[req->size - 1];
302 
303  /* When the do_callback flag is set; it means the transfer is finished
304  * so set the FIFO as idle */
305  if (do_callback)
306  lpbfifo.req = NULL;
307 
308  if (irq != 0) /* don't increment on polled case */
309  req->irq_count++;
310 
311  req->irq_ticks += get_tbl() - ts;
312  spin_unlock_irqrestore(&lpbfifo.lock, flags);
313 
314  /* Spinlock is released; it is now safe to call the callback */
315  if (do_callback && req->callback)
316  req->callback(req);
317 
318  return IRQ_HANDLED;
319 }
320 
326 static irqreturn_t mpc52xx_lpbfifo_bcom_irq(int irq, void *dev_id)
327 {
329  unsigned long flags;
330  u32 status;
331  u32 ts;
332 
333  spin_lock_irqsave(&lpbfifo.lock, flags);
334  ts = get_tbl();
335 
336  req = lpbfifo.req;
337  if (!req || (req->flags & MPC52XX_LPBFIFO_FLAG_NO_DMA)) {
338  spin_unlock_irqrestore(&lpbfifo.lock, flags);
339  return IRQ_HANDLED;
340  }
341 
342  if (irq != 0) /* don't increment on polled case */
343  req->irq_count++;
344 
345  if (!bcom_buffer_done(lpbfifo.bcom_cur_task)) {
346  spin_unlock_irqrestore(&lpbfifo.lock, flags);
347 
348  req->buffer_not_done_cnt++;
349  if ((req->buffer_not_done_cnt % 1000) == 0)
350  pr_err("transfer stalled\n");
351 
352  return IRQ_HANDLED;
353  }
354 
355  bcom_retrieve_buffer(lpbfifo.bcom_cur_task, &status, NULL);
356 
357  req->last_byte = ((u8 *)req->data)[req->size - 1];
358 
359  req->pos = status & 0x00ffffff;
360 
361  /* Mark the FIFO as idle */
362  lpbfifo.req = NULL;
363 
364  /* Release the lock before calling out to the callback. */
365  req->irq_ticks += get_tbl() - ts;
366  spin_unlock_irqrestore(&lpbfifo.lock, flags);
367 
368  if (req->callback)
369  req->callback(req);
370 
371  return IRQ_HANDLED;
372 }
373 
378 {
379  struct mpc52xx_lpbfifo_request *req = lpbfifo.req;
380  int dma = !(req->flags & MPC52XX_LPBFIFO_FLAG_NO_DMA);
381  int write = req->flags & MPC52XX_LPBFIFO_FLAG_WRITE;
382 
383  /*
384  * For more information, see comments on the "Fat Lady"
385  */
386  if (dma && write)
387  mpc52xx_lpbfifo_irq(0, NULL);
388  else
389  mpc52xx_lpbfifo_bcom_irq(0, NULL);
390 }
392 
398 {
399  unsigned long flags;
400 
401  if (!lpbfifo.regs)
402  return -ENODEV;
403 
404  spin_lock_irqsave(&lpbfifo.lock, flags);
405 
406  /* If the req pointer is already set, then a transfer is in progress */
407  if (lpbfifo.req) {
408  spin_unlock_irqrestore(&lpbfifo.lock, flags);
409  return -EBUSY;
410  }
411 
412  /* Setup the transfer */
413  lpbfifo.req = req;
414  req->irq_count = 0;
415  req->irq_ticks = 0;
416  req->buffer_not_done_cnt = 0;
417  req->pos = 0;
418 
419  mpc52xx_lpbfifo_kick(req);
420  spin_unlock_irqrestore(&lpbfifo.lock, flags);
421  return 0;
422 }
424 
426 {
427  unsigned long flags;
428 
429  if (!lpbfifo.regs)
430  return -ENODEV;
431 
432  spin_lock_irqsave(&lpbfifo.lock, flags);
433 
434  /*
435  * If the req pointer is already set and a transfer was
436  * started on submit, then this transfer is in progress
437  */
438  if (lpbfifo.req && !lpbfifo.req->defer_xfer_start) {
439  spin_unlock_irqrestore(&lpbfifo.lock, flags);
440  return -EBUSY;
441  }
442 
443  /*
444  * If the req was previously submitted but not
445  * started, start it now
446  */
447  if (lpbfifo.req && lpbfifo.req == req &&
448  lpbfifo.req->defer_xfer_start) {
449  out_8(lpbfifo.regs + LPBFIFO_REG_PACKET_SIZE, 0x01);
450  }
451 
452  spin_unlock_irqrestore(&lpbfifo.lock, flags);
453  return 0;
454 }
456 
458 {
459  unsigned long flags;
460 
461  spin_lock_irqsave(&lpbfifo.lock, flags);
462  if (lpbfifo.req == req) {
463  /* Put it into reset and clear the state */
464  bcom_gen_bd_rx_reset(lpbfifo.bcom_rx_task);
465  bcom_gen_bd_tx_reset(lpbfifo.bcom_tx_task);
466  out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
467  lpbfifo.req = NULL;
468  }
469  spin_unlock_irqrestore(&lpbfifo.lock, flags);
470 }
472 
473 static int __devinit mpc52xx_lpbfifo_probe(struct platform_device *op)
474 {
475  struct resource res;
476  int rc = -ENOMEM;
477 
478  if (lpbfifo.dev != NULL)
479  return -ENOSPC;
480 
481  lpbfifo.irq = irq_of_parse_and_map(op->dev.of_node, 0);
482  if (!lpbfifo.irq)
483  return -ENODEV;
484 
485  if (of_address_to_resource(op->dev.of_node, 0, &res))
486  return -ENODEV;
487  lpbfifo.regs_phys = res.start;
488  lpbfifo.regs = of_iomap(op->dev.of_node, 0);
489  if (!lpbfifo.regs)
490  return -ENOMEM;
491 
492  spin_lock_init(&lpbfifo.lock);
493 
494  /* Put FIFO into reset */
495  out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
496 
497  /* Register the interrupt handler */
498  rc = request_irq(lpbfifo.irq, mpc52xx_lpbfifo_irq, 0,
499  "mpc52xx-lpbfifo", &lpbfifo);
500  if (rc)
501  goto err_irq;
502 
503  /* Request the Bestcomm receive (fifo --> memory) task and IRQ */
504  lpbfifo.bcom_rx_task =
507  16*1024*1024);
508  if (!lpbfifo.bcom_rx_task)
509  goto err_bcom_rx;
510 
511  rc = request_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task),
512  mpc52xx_lpbfifo_bcom_irq, 0,
513  "mpc52xx-lpbfifo-rx", &lpbfifo);
514  if (rc)
515  goto err_bcom_rx_irq;
516 
517  lpbfifo.dma_irqs_enabled = 1;
518 
519  /* Request the Bestcomm transmit (memory --> fifo) task and IRQ */
520  lpbfifo.bcom_tx_task =
523  if (!lpbfifo.bcom_tx_task)
524  goto err_bcom_tx;
525 
526  lpbfifo.dev = &op->dev;
527  return 0;
528 
529  err_bcom_tx:
530  free_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task), &lpbfifo);
531  err_bcom_rx_irq:
532  bcom_gen_bd_rx_release(lpbfifo.bcom_rx_task);
533  err_bcom_rx:
534  err_irq:
535  iounmap(lpbfifo.regs);
536  lpbfifo.regs = NULL;
537 
538  dev_err(&op->dev, "mpc52xx_lpbfifo_probe() failed\n");
539  return -ENODEV;
540 }
541 
542 
543 static int __devexit mpc52xx_lpbfifo_remove(struct platform_device *op)
544 {
545  if (lpbfifo.dev != &op->dev)
546  return 0;
547 
548  /* Put FIFO in reset */
549  out_be32(lpbfifo.regs + LPBFIFO_REG_ENABLE, 0x01010000);
550 
551  /* Release the bestcomm transmit task */
552  free_irq(bcom_get_task_irq(lpbfifo.bcom_tx_task), &lpbfifo);
553  bcom_gen_bd_tx_release(lpbfifo.bcom_tx_task);
554 
555  /* Release the bestcomm receive task */
556  free_irq(bcom_get_task_irq(lpbfifo.bcom_rx_task), &lpbfifo);
557  bcom_gen_bd_rx_release(lpbfifo.bcom_rx_task);
558 
559  free_irq(lpbfifo.irq, &lpbfifo);
560  iounmap(lpbfifo.regs);
561  lpbfifo.regs = NULL;
562  lpbfifo.dev = NULL;
563 
564  return 0;
565 }
566 
567 static struct of_device_id mpc52xx_lpbfifo_match[] __devinitconst = {
568  { .compatible = "fsl,mpc5200-lpbfifo", },
569  {},
570 };
571 
572 static struct platform_driver mpc52xx_lpbfifo_driver = {
573  .driver = {
574  .name = "mpc52xx-lpbfifo",
575  .owner = THIS_MODULE,
576  .of_match_table = mpc52xx_lpbfifo_match,
577  },
578  .probe = mpc52xx_lpbfifo_probe,
579  .remove = __devexit_p(mpc52xx_lpbfifo_remove),
580 };
581 
582 /***********************************************************************
583  * Module init/exit
584  */
585 static int __init mpc52xx_lpbfifo_init(void)
586 {
587  return platform_driver_register(&mpc52xx_lpbfifo_driver);
588 }
589 module_init(mpc52xx_lpbfifo_init);
590 
591 static void __exit mpc52xx_lpbfifo_exit(void)
592 {
593  platform_driver_unregister(&mpc52xx_lpbfifo_driver);
594 }
595 module_exit(mpc52xx_lpbfifo_exit);