Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
rack-meter.c
Go to the documentation of this file.
1 /*
2  * RackMac vu-meter driver
3  *
4  * (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp.
6  *
7  * Released under the term of the GNU GPL v2.
8  *
9  * Support the CPU-meter LEDs of the Xserve G5
10  *
11  * TODO: Implement PWM to do variable intensity and provide userland
12  * interface for fun. Also, the CPU-meter could be made nicer by being
13  * a bit less "immediate" but giving instead a more average load over
14  * time. Patches welcome :-)
15  *
16  */
17 #undef DEBUG
18 
19 #include <linux/types.h>
20 #include <linux/kernel.h>
21 #include <linux/slab.h>
22 #include <linux/device.h>
23 #include <linux/interrupt.h>
24 #include <linux/module.h>
25 #include <linux/pci.h>
26 #include <linux/dma-mapping.h>
27 #include <linux/kernel_stat.h>
28 
29 #include <asm/io.h>
30 #include <asm/prom.h>
31 #include <asm/machdep.h>
32 #include <asm/pmac_feature.h>
33 #include <asm/dbdma.h>
34 #include <asm/macio.h>
35 #include <asm/keylargo.h>
36 
37 /* Number of samples in a sample buffer */
38 #define SAMPLE_COUNT 256
39 
40 /* CPU meter sampling rate in ms */
41 #define CPU_SAMPLING_RATE 250
42 
43 struct rackmeter_dma {
44  struct dbdma_cmd cmd[4] ____cacheline_aligned;
49 
50 struct rackmeter_cpu {
52  struct rackmeter *rm;
55  int zero;
57 
58 struct rackmeter {
59  struct macio_dev *mdev;
60  unsigned int irq;
61  struct device_node *i2s;
62  u8 *ubuf;
63  struct dbdma_regs __iomem *dma_regs;
67  int stale_irq;
68  struct rackmeter_cpu cpu[2];
69  int paused;
70  struct mutex sem;
71 };
72 
73 /* To be set as a tunable */
74 static int rackmeter_ignore_nice;
75 
76 /* This GPIO is whacked by the OS X driver when initializing */
77 #define RACKMETER_MAGIC_GPIO 0x78
78 
79 /* This is copied from cpufreq_ondemand, maybe we should put it in
80  * a common header somewhere
81  */
82 static inline cputime64_t get_cpu_idle_time(unsigned int cpu)
83 {
84  u64 retval;
85 
86  retval = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE] +
87  kcpustat_cpu(cpu).cpustat[CPUTIME_IOWAIT];
88 
89  if (rackmeter_ignore_nice)
90  retval += kcpustat_cpu(cpu).cpustat[CPUTIME_NICE];
91 
92  return retval;
93 }
94 
95 static void rackmeter_setup_i2s(struct rackmeter *rm)
96 {
97  struct macio_chip *macio = rm->mdev->bus->chip;
98 
99  /* First whack magic GPIO */
100  pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, RACKMETER_MAGIC_GPIO, 5);
101 
102 
103  /* Call feature code to enable the sound channel and the proper
104  * clock sources
105  */
106  pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, rm->i2s, 0, 1);
107 
108  /* Power i2s and stop i2s clock. We whack MacIO FCRs directly for now.
109  * This is a bit racy, thus we should add new platform functions to
110  * handle that. snd-aoa needs that too
111  */
112  MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_ENABLE);
113  MACIO_BIC(KEYLARGO_FCR1, KL1_I2S0_CLK_ENABLE_BIT);
114  (void)MACIO_IN32(KEYLARGO_FCR1);
115  udelay(10);
116 
117  /* Then setup i2s. For now, we use the same magic value that
118  * the OS X driver seems to use. We might want to play around
119  * with the clock divisors later
120  */
121  out_le32(rm->i2s_regs + 0x10, 0x01fa0000);
122  (void)in_le32(rm->i2s_regs + 0x10);
123  udelay(10);
124 
125  /* Fully restart i2s*/
126  MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_CELL_ENABLE |
127  KL1_I2S0_CLK_ENABLE_BIT);
128  (void)MACIO_IN32(KEYLARGO_FCR1);
129  udelay(10);
130 }
131 
132 static void rackmeter_set_default_pattern(struct rackmeter *rm)
133 {
134  int i;
135 
136  for (i = 0; i < 16; i++) {
137  if (i < 8)
138  rm->ubuf[i] = (i & 1) * 255;
139  else
140  rm->ubuf[i] = ((~i) & 1) * 255;
141  }
142 }
143 
144 static void rackmeter_do_pause(struct rackmeter *rm, int pause)
145 {
146  struct rackmeter_dma *rdma = rm->dma_buf_v;
147 
148  pr_debug("rackmeter: %s\n", pause ? "paused" : "started");
149 
150  rm->paused = pause;
151  if (pause) {
152  DBDMA_DO_STOP(rm->dma_regs);
153  return;
154  }
155  memset(rdma->buf1, 0, SAMPLE_COUNT & sizeof(u32));
156  memset(rdma->buf2, 0, SAMPLE_COUNT & sizeof(u32));
157 
158  rm->dma_buf_v->mark = 0;
159 
160  mb();
161  out_le32(&rm->dma_regs->cmdptr_hi, 0);
162  out_le32(&rm->dma_regs->cmdptr, rm->dma_buf_p);
163  out_le32(&rm->dma_regs->control, (RUN << 16) | RUN);
164 }
165 
166 static void rackmeter_setup_dbdma(struct rackmeter *rm)
167 {
168  struct rackmeter_dma *db = rm->dma_buf_v;
169  struct dbdma_cmd *cmd = db->cmd;
170 
171  /* Make sure dbdma is reset */
172  DBDMA_DO_RESET(rm->dma_regs);
173 
174  pr_debug("rackmeter: mark offset=0x%zx\n",
175  offsetof(struct rackmeter_dma, mark));
176  pr_debug("rackmeter: buf1 offset=0x%zx\n",
177  offsetof(struct rackmeter_dma, buf1));
178  pr_debug("rackmeter: buf2 offset=0x%zx\n",
179  offsetof(struct rackmeter_dma, buf2));
180 
181  /* Prepare 4 dbdma commands for the 2 buffers */
182  memset(cmd, 0, 4 * sizeof(struct dbdma_cmd));
183  st_le16(&cmd->req_count, 4);
184  st_le16(&cmd->command, STORE_WORD | INTR_ALWAYS | KEY_SYSTEM);
185  st_le32(&cmd->phy_addr, rm->dma_buf_p +
186  offsetof(struct rackmeter_dma, mark));
187  st_le32(&cmd->cmd_dep, 0x02000000);
188  cmd++;
189 
190  st_le16(&cmd->req_count, SAMPLE_COUNT * 4);
191  st_le16(&cmd->command, OUTPUT_MORE);
192  st_le32(&cmd->phy_addr, rm->dma_buf_p +
193  offsetof(struct rackmeter_dma, buf1));
194  cmd++;
195 
196  st_le16(&cmd->req_count, 4);
197  st_le16(&cmd->command, STORE_WORD | INTR_ALWAYS | KEY_SYSTEM);
198  st_le32(&cmd->phy_addr, rm->dma_buf_p +
199  offsetof(struct rackmeter_dma, mark));
200  st_le32(&cmd->cmd_dep, 0x01000000);
201  cmd++;
202 
203  st_le16(&cmd->req_count, SAMPLE_COUNT * 4);
204  st_le16(&cmd->command, OUTPUT_MORE | BR_ALWAYS);
205  st_le32(&cmd->phy_addr, rm->dma_buf_p +
206  offsetof(struct rackmeter_dma, buf2));
207  st_le32(&cmd->cmd_dep, rm->dma_buf_p);
208 
209  rackmeter_do_pause(rm, 0);
210 }
211 
212 static void rackmeter_do_timer(struct work_struct *work)
213 {
214  struct rackmeter_cpu *rcpu =
215  container_of(work, struct rackmeter_cpu, sniffer.work);
216  struct rackmeter *rm = rcpu->rm;
217  unsigned int cpu = smp_processor_id();
218  cputime64_t cur_jiffies, total_idle_ticks;
219  unsigned int total_ticks, idle_ticks;
220  int i, offset, load, cumm, pause;
221 
222  cur_jiffies = jiffies64_to_cputime64(get_jiffies_64());
223  total_ticks = (unsigned int) (cur_jiffies - rcpu->prev_wall);
224  rcpu->prev_wall = cur_jiffies;
225 
226  total_idle_ticks = get_cpu_idle_time(cpu);
227  idle_ticks = (unsigned int) (total_idle_ticks - rcpu->prev_idle);
228  rcpu->prev_idle = total_idle_ticks;
229 
230  /* We do a very dumb calculation to update the LEDs for now,
231  * we'll do better once we have actual PWM implemented
232  */
233  load = (9 * (total_ticks - idle_ticks)) / total_ticks;
234 
235  offset = cpu << 3;
236  cumm = 0;
237  for (i = 0; i < 8; i++) {
238  u8 ub = (load > i) ? 0xff : 0;
239  rm->ubuf[i + offset] = ub;
240  cumm |= ub;
241  }
242  rcpu->zero = (cumm == 0);
243 
244  /* Now check if LEDs are all 0, we can stop DMA */
245  pause = (rm->cpu[0].zero && rm->cpu[1].zero);
246  if (pause != rm->paused) {
247  mutex_lock(&rm->sem);
248  pause = (rm->cpu[0].zero && rm->cpu[1].zero);
249  rackmeter_do_pause(rm, pause);
250  mutex_unlock(&rm->sem);
251  }
252  schedule_delayed_work_on(cpu, &rcpu->sniffer,
254 }
255 
256 static void __devinit rackmeter_init_cpu_sniffer(struct rackmeter *rm)
257 {
258  unsigned int cpu;
259 
260  /* This driver works only with 1 or 2 CPUs numbered 0 and 1,
261  * but that's really all we have on Apple Xserve. It doesn't
262  * play very nice with CPU hotplug neither but we don't do that
263  * on those machines yet
264  */
265 
266  rm->cpu[0].rm = rm;
267  INIT_DELAYED_WORK(&rm->cpu[0].sniffer, rackmeter_do_timer);
268  rm->cpu[1].rm = rm;
269  INIT_DELAYED_WORK(&rm->cpu[1].sniffer, rackmeter_do_timer);
270 
271  for_each_online_cpu(cpu) {
272  struct rackmeter_cpu *rcpu;
273 
274  if (cpu > 1)
275  continue;
276  rcpu = &rm->cpu[cpu];
277  rcpu->prev_idle = get_cpu_idle_time(cpu);
279  schedule_delayed_work_on(cpu, &rm->cpu[cpu].sniffer,
281  }
282 }
283 
284 static void rackmeter_stop_cpu_sniffer(struct rackmeter *rm)
285 {
286  cancel_delayed_work_sync(&rm->cpu[0].sniffer);
287  cancel_delayed_work_sync(&rm->cpu[1].sniffer);
288 }
289 
290 static int __devinit rackmeter_setup(struct rackmeter *rm)
291 {
292  pr_debug("rackmeter: setting up i2s..\n");
293  rackmeter_setup_i2s(rm);
294 
295  pr_debug("rackmeter: setting up default pattern..\n");
296  rackmeter_set_default_pattern(rm);
297 
298  pr_debug("rackmeter: setting up dbdma..\n");
299  rackmeter_setup_dbdma(rm);
300 
301  pr_debug("rackmeter: start CPU measurements..\n");
302  rackmeter_init_cpu_sniffer(rm);
303 
304  printk(KERN_INFO "RackMeter initialized\n");
305 
306  return 0;
307 }
308 
309 /* XXX FIXME: No PWM yet, this is 0/1 */
310 static u32 rackmeter_calc_sample(struct rackmeter *rm, unsigned int index)
311 {
312  int led;
313  u32 sample = 0;
314 
315  for (led = 0; led < 16; led++) {
316  sample >>= 1;
317  sample |= ((rm->ubuf[led] >= 0x80) << 15);
318  }
319  return (sample << 17) | (sample >> 15);
320 }
321 
322 static irqreturn_t rackmeter_irq(int irq, void *arg)
323 {
324  struct rackmeter *rm = arg;
325  struct rackmeter_dma *db = rm->dma_buf_v;
326  unsigned int mark, i;
327  u32 *buf;
328 
329  /* Flush PCI buffers with an MMIO read. Maybe we could actually
330  * check the status one day ... in case things go wrong, though
331  * this never happened to me
332  */
333  (void)in_le32(&rm->dma_regs->status);
334 
335  /* Make sure the CPU gets us in order */
336  rmb();
337 
338  /* Read mark */
339  mark = db->mark;
340  if (mark != 1 && mark != 2) {
341  printk(KERN_WARNING "rackmeter: Incorrect DMA mark 0x%08x\n",
342  mark);
343  /* We allow for 3 errors like that (stale DBDMA irqs) */
344  if (++rm->stale_irq > 3) {
345  printk(KERN_ERR "rackmeter: Too many errors,"
346  " stopping DMA\n");
347  DBDMA_DO_RESET(rm->dma_regs);
348  }
349  return IRQ_HANDLED;
350  }
351 
352  /* Next buffer we need to fill is mark value */
353  buf = mark == 1 ? db->buf1 : db->buf2;
354 
355  /* Fill it now. This routine converts the 8 bits depth sample array
356  * into the PWM bitmap for each LED.
357  */
358  for (i = 0; i < SAMPLE_COUNT; i++)
359  buf[i] = rackmeter_calc_sample(rm, i);
360 
361 
362  return IRQ_HANDLED;
363 }
364 
365 static int __devinit rackmeter_probe(struct macio_dev* mdev,
366  const struct of_device_id *match)
367 {
368  struct device_node *i2s = NULL, *np = NULL;
369  struct rackmeter *rm = NULL;
370  struct resource ri2s, rdma;
371  int rc = -ENODEV;
372 
373  pr_debug("rackmeter_probe()\n");
374 
375  /* Get i2s-a node */
376  while ((i2s = of_get_next_child(mdev->ofdev.dev.of_node, i2s)) != NULL)
377  if (strcmp(i2s->name, "i2s-a") == 0)
378  break;
379  if (i2s == NULL) {
380  pr_debug(" i2s-a child not found\n");
381  goto bail;
382  }
383  /* Get lightshow or virtual sound */
384  while ((np = of_get_next_child(i2s, np)) != NULL) {
385  if (strcmp(np->name, "lightshow") == 0)
386  break;
387  if ((strcmp(np->name, "sound") == 0) &&
388  of_get_property(np, "virtual", NULL) != NULL)
389  break;
390  }
391  if (np == NULL) {
392  pr_debug(" lightshow or sound+virtual child not found\n");
393  goto bail;
394  }
395 
396  /* Create and initialize our instance data */
397  rm = kzalloc(sizeof(struct rackmeter), GFP_KERNEL);
398  if (rm == NULL) {
399  printk(KERN_ERR "rackmeter: failed to allocate memory !\n");
400  rc = -ENOMEM;
401  goto bail_release;
402  }
403  rm->mdev = mdev;
404  rm->i2s = i2s;
405  mutex_init(&rm->sem);
406  dev_set_drvdata(&mdev->ofdev.dev, rm);
407  /* Check resources availability. We need at least resource 0 and 1 */
408 #if 0 /* Use that when i2s-a is finally an mdev per-se */
409  if (macio_resource_count(mdev) < 2 || macio_irq_count(mdev) < 2) {
411  "rackmeter: found match but lacks resources: %s"
412  " (%d resources, %d interrupts)\n",
413  mdev->ofdev.node->full_name);
414  rc = -ENXIO;
415  goto bail_free;
416  }
417  if (macio_request_resources(mdev, "rackmeter")) {
419  "rackmeter: failed to request resources: %s\n",
420  mdev->ofdev.node->full_name);
421  rc = -EBUSY;
422  goto bail_free;
423  }
424  rm->irq = macio_irq(mdev, 1);
425 #else
426  rm->irq = irq_of_parse_and_map(i2s, 1);
427  if (rm->irq == NO_IRQ ||
428  of_address_to_resource(i2s, 0, &ri2s) ||
429  of_address_to_resource(i2s, 1, &rdma)) {
431  "rackmeter: found match but lacks resources: %s",
432  mdev->ofdev.dev.of_node->full_name);
433  rc = -ENXIO;
434  goto bail_free;
435  }
436 #endif
437 
438  pr_debug(" i2s @0x%08x\n", (unsigned int)ri2s.start);
439  pr_debug(" dma @0x%08x\n", (unsigned int)rdma.start);
440  pr_debug(" irq %d\n", rm->irq);
441 
442  rm->ubuf = (u8 *)__get_free_page(GFP_KERNEL);
443  if (rm->ubuf == NULL) {
445  "rackmeter: failed to allocate samples page !\n");
446  rc = -ENOMEM;
447  goto bail_release;
448  }
449 
450  rm->dma_buf_v = dma_alloc_coherent(&macio_get_pci_dev(mdev)->dev,
451  sizeof(struct rackmeter_dma),
452  &rm->dma_buf_p, GFP_KERNEL);
453  if (rm->dma_buf_v == NULL) {
455  "rackmeter: failed to allocate dma buffer !\n");
456  rc = -ENOMEM;
457  goto bail_free_samples;
458  }
459 #if 0
460  rm->i2s_regs = ioremap(macio_resource_start(mdev, 0), 0x1000);
461 #else
462  rm->i2s_regs = ioremap(ri2s.start, 0x1000);
463 #endif
464  if (rm->i2s_regs == NULL) {
466  "rackmeter: failed to map i2s registers !\n");
467  rc = -ENXIO;
468  goto bail_free_dma;
469  }
470 #if 0
471  rm->dma_regs = ioremap(macio_resource_start(mdev, 1), 0x100);
472 #else
473  rm->dma_regs = ioremap(rdma.start, 0x100);
474 #endif
475  if (rm->dma_regs == NULL) {
477  "rackmeter: failed to map dma registers !\n");
478  rc = -ENXIO;
479  goto bail_unmap_i2s;
480  }
481 
482  rc = rackmeter_setup(rm);
483  if (rc) {
485  "rackmeter: failed to initialize !\n");
486  rc = -ENXIO;
487  goto bail_unmap_dma;
488  }
489 
490  rc = request_irq(rm->irq, rackmeter_irq, 0, "rackmeter", rm);
491  if (rc != 0) {
493  "rackmeter: failed to request interrupt !\n");
494  goto bail_stop_dma;
495  }
496  of_node_put(np);
497  return 0;
498 
499  bail_stop_dma:
500  DBDMA_DO_RESET(rm->dma_regs);
501  bail_unmap_dma:
502  iounmap(rm->dma_regs);
503  bail_unmap_i2s:
504  iounmap(rm->i2s_regs);
505  bail_free_dma:
506  dma_free_coherent(&macio_get_pci_dev(mdev)->dev,
507  sizeof(struct rackmeter_dma),
508  rm->dma_buf_v, rm->dma_buf_p);
509  bail_free_samples:
510  free_page((unsigned long)rm->ubuf);
511  bail_release:
512 #if 0
514 #endif
515  bail_free:
516  kfree(rm);
517  bail:
518  of_node_put(i2s);
519  of_node_put(np);
520  dev_set_drvdata(&mdev->ofdev.dev, NULL);
521  return rc;
522 }
523 
524 static int __devexit rackmeter_remove(struct macio_dev* mdev)
525 {
526  struct rackmeter *rm = dev_get_drvdata(&mdev->ofdev.dev);
527 
528  /* Stop CPU sniffer timer & work queues */
529  rackmeter_stop_cpu_sniffer(rm);
530 
531  /* Clear reference to private data */
532  dev_set_drvdata(&mdev->ofdev.dev, NULL);
533 
534  /* Stop/reset dbdma */
535  DBDMA_DO_RESET(rm->dma_regs);
536 
537  /* Release the IRQ */
538  free_irq(rm->irq, rm);
539 
540  /* Unmap registers */
541  iounmap(rm->dma_regs);
542  iounmap(rm->i2s_regs);
543 
544  /* Free DMA */
545  dma_free_coherent(&macio_get_pci_dev(mdev)->dev,
546  sizeof(struct rackmeter_dma),
547  rm->dma_buf_v, rm->dma_buf_p);
548 
549  /* Free samples */
550  free_page((unsigned long)rm->ubuf);
551 
552 #if 0
553  /* Release resources */
555 #endif
556 
557  /* Get rid of me */
558  kfree(rm);
559 
560  return 0;
561 }
562 
563 static int rackmeter_shutdown(struct macio_dev* mdev)
564 {
565  struct rackmeter *rm = dev_get_drvdata(&mdev->ofdev.dev);
566 
567  if (rm == NULL)
568  return -ENODEV;
569 
570  /* Stop CPU sniffer timer & work queues */
571  rackmeter_stop_cpu_sniffer(rm);
572 
573  /* Stop/reset dbdma */
574  DBDMA_DO_RESET(rm->dma_regs);
575 
576  return 0;
577 }
578 
579 static struct of_device_id rackmeter_match[] = {
580  { .name = "i2s" },
581  { }
582 };
583 
584 static struct macio_driver rackmeter_driver = {
585  .driver = {
586  .name = "rackmeter",
587  .owner = THIS_MODULE,
588  .of_match_table = rackmeter_match,
589  },
590  .probe = rackmeter_probe,
591  .remove = __devexit_p(rackmeter_remove),
592  .shutdown = rackmeter_shutdown,
593 };
594 
595 
596 static int __init rackmeter_init(void)
597 {
598  pr_debug("rackmeter_init()\n");
599 
600  return macio_register_driver(&rackmeter_driver);
601 }
602 
603 static void __exit rackmeter_exit(void)
604 {
605  pr_debug("rackmeter_exit()\n");
606 
607  macio_unregister_driver(&rackmeter_driver);
608 }
609 
610 module_init(rackmeter_init);
611 module_exit(rackmeter_exit);
612 
613 
614 MODULE_LICENSE("GPL");
615 MODULE_AUTHOR("Benjamin Herrenschmidt <[email protected]>");
616 MODULE_DESCRIPTION("RackMeter: Support vu-meter on XServe front panel");