These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / hwtracing / intel_th / gth.c
1 /*
2  * Intel(R) Trace Hub Global Trace Hub
3  *
4  * Copyright (C) 2014-2015 Intel Corporation.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  */
15
16 #define pr_fmt(fmt)     KBUILD_MODNAME ": " fmt
17
18 #include <linux/types.h>
19 #include <linux/module.h>
20 #include <linux/device.h>
21 #include <linux/io.h>
22 #include <linux/mm.h>
23 #include <linux/slab.h>
24 #include <linux/bitmap.h>
25
26 #include "intel_th.h"
27 #include "gth.h"
28
29 struct gth_device;
30
31 /**
32  * struct gth_output - GTH view on an output port
33  * @gth:        backlink to the GTH device
34  * @output:     link to output device's output descriptor
35  * @index:      output port number
36  * @port_type:  one of GTH_* port type values
37  * @master:     bitmap of masters configured for this output
38  */
39 struct gth_output {
40         struct gth_device       *gth;
41         struct intel_th_output  *output;
42         unsigned int            index;
43         unsigned int            port_type;
44         DECLARE_BITMAP(master, TH_CONFIGURABLE_MASTERS + 1);
45 };
46
47 /**
48  * struct gth_device - GTH device
49  * @dev:        driver core's device
50  * @base:       register window base address
51  * @output_group:       attributes describing output ports
52  * @master_group:       attributes describing master assignments
53  * @output:             output ports
54  * @master:             master/output port assignments
55  * @gth_lock:           serializes accesses to GTH bits
56  */
57 struct gth_device {
58         struct device           *dev;
59         void __iomem            *base;
60
61         struct attribute_group  output_group;
62         struct attribute_group  master_group;
63         struct gth_output       output[TH_POSSIBLE_OUTPUTS];
64         signed char             master[TH_CONFIGURABLE_MASTERS + 1];
65         spinlock_t              gth_lock;
66 };
67
68 static void gth_output_set(struct gth_device *gth, int port,
69                            unsigned int config)
70 {
71         unsigned long reg = port & 4 ? REG_GTH_GTHOPT1 : REG_GTH_GTHOPT0;
72         u32 val;
73         int shift = (port & 3) * 8;
74
75         val = ioread32(gth->base + reg);
76         val &= ~(0xff << shift);
77         val |= config << shift;
78         iowrite32(val, gth->base + reg);
79 }
80
81 static unsigned int gth_output_get(struct gth_device *gth, int port)
82 {
83         unsigned long reg = port & 4 ? REG_GTH_GTHOPT1 : REG_GTH_GTHOPT0;
84         u32 val;
85         int shift = (port & 3) * 8;
86
87         val = ioread32(gth->base + reg);
88         val &= 0xff << shift;
89         val >>= shift;
90
91         return val;
92 }
93
94 static void gth_smcfreq_set(struct gth_device *gth, int port,
95                             unsigned int freq)
96 {
97         unsigned long reg = REG_GTH_SMCR0 + ((port / 2) * 4);
98         int shift = (port & 1) * 16;
99         u32 val;
100
101         val = ioread32(gth->base + reg);
102         val &= ~(0xffff << shift);
103         val |= freq << shift;
104         iowrite32(val, gth->base + reg);
105 }
106
107 static unsigned int gth_smcfreq_get(struct gth_device *gth, int port)
108 {
109         unsigned long reg = REG_GTH_SMCR0 + ((port / 2) * 4);
110         int shift = (port & 1) * 16;
111         u32 val;
112
113         val = ioread32(gth->base + reg);
114         val &= 0xffff << shift;
115         val >>= shift;
116
117         return val;
118 }
119
120 /*
121  * "masters" attribute group
122  */
123
124 struct master_attribute {
125         struct device_attribute attr;
126         struct gth_device       *gth;
127         unsigned int            master;
128 };
129
130 static void
131 gth_master_set(struct gth_device *gth, unsigned int master, int port)
132 {
133         unsigned int reg = REG_GTH_SWDEST0 + ((master >> 1) & ~3u);
134         unsigned int shift = (master & 0x7) * 4;
135         u32 val;
136
137         if (master >= 256) {
138                 reg = REG_GTH_GSWTDEST;
139                 shift = 0;
140         }
141
142         val = ioread32(gth->base + reg);
143         val &= ~(0xf << shift);
144         if (port >= 0)
145                 val |= (0x8 | port) << shift;
146         iowrite32(val, gth->base + reg);
147 }
148
149 /*static int gth_master_get(struct gth_device *gth, unsigned int master)
150 {
151         unsigned int reg = REG_GTH_SWDEST0 + ((master >> 1) & ~3u);
152         unsigned int shift = (master & 0x7) * 4;
153         u32 val;
154
155         if (master >= 256) {
156                 reg = REG_GTH_GSWTDEST;
157                 shift = 0;
158         }
159
160         val = ioread32(gth->base + reg);
161         val &= (0xf << shift);
162         val >>= shift;
163
164         return val ? val & 0x7 : -1;
165         }*/
166
167 static ssize_t master_attr_show(struct device *dev,
168                                 struct device_attribute *attr,
169                                 char *buf)
170 {
171         struct master_attribute *ma =
172                 container_of(attr, struct master_attribute, attr);
173         struct gth_device *gth = ma->gth;
174         size_t count;
175         int port;
176
177         spin_lock(&gth->gth_lock);
178         port = gth->master[ma->master];
179         spin_unlock(&gth->gth_lock);
180
181         if (port >= 0)
182                 count = snprintf(buf, PAGE_SIZE, "%x\n", port);
183         else
184                 count = snprintf(buf, PAGE_SIZE, "disabled\n");
185
186         return count;
187 }
188
189 static ssize_t master_attr_store(struct device *dev,
190                                  struct device_attribute *attr,
191                                  const char *buf, size_t count)
192 {
193         struct master_attribute *ma =
194                 container_of(attr, struct master_attribute, attr);
195         struct gth_device *gth = ma->gth;
196         int old_port, port;
197
198         if (kstrtoint(buf, 10, &port) < 0)
199                 return -EINVAL;
200
201         if (port >= TH_POSSIBLE_OUTPUTS || port < -1)
202                 return -EINVAL;
203
204         spin_lock(&gth->gth_lock);
205
206         /* disconnect from the previous output port, if any */
207         old_port = gth->master[ma->master];
208         if (old_port >= 0) {
209                 gth->master[ma->master] = -1;
210                 clear_bit(ma->master, gth->output[old_port].master);
211                 if (gth->output[old_port].output->active)
212                         gth_master_set(gth, ma->master, -1);
213         }
214
215         /* connect to the new output port, if any */
216         if (port >= 0) {
217                 /* check if there's a driver for this port */
218                 if (!gth->output[port].output) {
219                         count = -ENODEV;
220                         goto unlock;
221                 }
222
223                 set_bit(ma->master, gth->output[port].master);
224
225                 /* if the port is active, program this setting */
226                 if (gth->output[port].output->active)
227                         gth_master_set(gth, ma->master, port);
228         }
229
230         gth->master[ma->master] = port;
231
232 unlock:
233         spin_unlock(&gth->gth_lock);
234
235         return count;
236 }
237
238 struct output_attribute {
239         struct device_attribute attr;
240         struct gth_device       *gth;
241         unsigned int            port;
242         unsigned int            parm;
243 };
244
245 #define OUTPUT_PARM(_name, _mask, _r, _w, _what)                        \
246         [TH_OUTPUT_PARM(_name)] = { .name = __stringify(_name),         \
247                                     .get = gth_ ## _what ## _get,       \
248                                     .set = gth_ ## _what ## _set,       \
249                                     .mask = (_mask),                    \
250                                     .readable = (_r),                   \
251                                     .writable = (_w) }
252
253 static const struct output_parm {
254         const char      *name;
255         unsigned int    (*get)(struct gth_device *gth, int port);
256         void            (*set)(struct gth_device *gth, int port,
257                                unsigned int val);
258         unsigned int    mask;
259         unsigned int    readable : 1,
260                         writable : 1;
261 } output_parms[] = {
262         OUTPUT_PARM(port,       0x7,    1, 0, output),
263         OUTPUT_PARM(null,       BIT(3), 1, 1, output),
264         OUTPUT_PARM(drop,       BIT(4), 1, 1, output),
265         OUTPUT_PARM(reset,      BIT(5), 1, 0, output),
266         OUTPUT_PARM(flush,      BIT(7), 0, 1, output),
267         OUTPUT_PARM(smcfreq,    0xffff, 1, 1, smcfreq),
268 };
269
270 static void
271 gth_output_parm_set(struct gth_device *gth, int port, unsigned int parm,
272                     unsigned int val)
273 {
274         unsigned int config = output_parms[parm].get(gth, port);
275         unsigned int mask = output_parms[parm].mask;
276         unsigned int shift = __ffs(mask);
277
278         config &= ~mask;
279         config |= (val << shift) & mask;
280         output_parms[parm].set(gth, port, config);
281 }
282
283 static unsigned int
284 gth_output_parm_get(struct gth_device *gth, int port, unsigned int parm)
285 {
286         unsigned int config = output_parms[parm].get(gth, port);
287         unsigned int mask = output_parms[parm].mask;
288         unsigned int shift = __ffs(mask);
289
290         config &= mask;
291         config >>= shift;
292         return config;
293 }
294
295 /*
296  * Reset outputs and sources
297  */
298 static int intel_th_gth_reset(struct gth_device *gth)
299 {
300         u32 scratchpad;
301         int port, i;
302
303         scratchpad = ioread32(gth->base + REG_GTH_SCRPD0);
304         if (scratchpad & SCRPD_DEBUGGER_IN_USE)
305                 return -EBUSY;
306
307         /* output ports */
308         for (port = 0; port < 8; port++) {
309                 if (gth_output_parm_get(gth, port, TH_OUTPUT_PARM(port)) ==
310                     GTH_NONE)
311                         continue;
312
313                 gth_output_set(gth, port, 0);
314                 gth_smcfreq_set(gth, port, 16);
315         }
316         /* disable overrides */
317         iowrite32(0, gth->base + REG_GTH_DESTOVR);
318
319         /* masters swdest_0~31 and gswdest */
320         for (i = 0; i < 33; i++)
321                 iowrite32(0, gth->base + REG_GTH_SWDEST0 + i * 4);
322
323         /* sources */
324         iowrite32(0, gth->base + REG_GTH_SCR);
325         iowrite32(0xfc, gth->base + REG_GTH_SCR2);
326
327         return 0;
328 }
329
330 /*
331  * "outputs" attribute group
332  */
333
334 static ssize_t output_attr_show(struct device *dev,
335                                 struct device_attribute *attr,
336                                 char *buf)
337 {
338         struct output_attribute *oa =
339                 container_of(attr, struct output_attribute, attr);
340         struct gth_device *gth = oa->gth;
341         size_t count;
342
343         spin_lock(&gth->gth_lock);
344         count = snprintf(buf, PAGE_SIZE, "%x\n",
345                          gth_output_parm_get(gth, oa->port, oa->parm));
346         spin_unlock(&gth->gth_lock);
347
348         return count;
349 }
350
351 static ssize_t output_attr_store(struct device *dev,
352                                  struct device_attribute *attr,
353                                  const char *buf, size_t count)
354 {
355         struct output_attribute *oa =
356                 container_of(attr, struct output_attribute, attr);
357         struct gth_device *gth = oa->gth;
358         unsigned int config;
359
360         if (kstrtouint(buf, 16, &config) < 0)
361                 return -EINVAL;
362
363         spin_lock(&gth->gth_lock);
364         gth_output_parm_set(gth, oa->port, oa->parm, config);
365         spin_unlock(&gth->gth_lock);
366
367         return count;
368 }
369
370 static int intel_th_master_attributes(struct gth_device *gth)
371 {
372         struct master_attribute *master_attrs;
373         struct attribute **attrs;
374         int i, nattrs = TH_CONFIGURABLE_MASTERS + 2;
375
376         attrs = devm_kcalloc(gth->dev, nattrs, sizeof(void *), GFP_KERNEL);
377         if (!attrs)
378                 return -ENOMEM;
379
380         master_attrs = devm_kcalloc(gth->dev, nattrs,
381                                     sizeof(struct master_attribute),
382                                     GFP_KERNEL);
383         if (!master_attrs)
384                 return -ENOMEM;
385
386         for (i = 0; i < TH_CONFIGURABLE_MASTERS + 1; i++) {
387                 char *name;
388
389                 name = devm_kasprintf(gth->dev, GFP_KERNEL, "%d%s", i,
390                                       i == TH_CONFIGURABLE_MASTERS ? "+" : "");
391                 if (!name)
392                         return -ENOMEM;
393
394                 master_attrs[i].attr.attr.name = name;
395                 master_attrs[i].attr.attr.mode = S_IRUGO | S_IWUSR;
396                 master_attrs[i].attr.show = master_attr_show;
397                 master_attrs[i].attr.store = master_attr_store;
398
399                 sysfs_attr_init(&master_attrs[i].attr.attr);
400                 attrs[i] = &master_attrs[i].attr.attr;
401
402                 master_attrs[i].gth = gth;
403                 master_attrs[i].master = i;
404         }
405
406         gth->master_group.name  = "masters";
407         gth->master_group.attrs = attrs;
408
409         return sysfs_create_group(&gth->dev->kobj, &gth->master_group);
410 }
411
412 static int intel_th_output_attributes(struct gth_device *gth)
413 {
414         struct output_attribute *out_attrs;
415         struct attribute **attrs;
416         int i, j, nouts = TH_POSSIBLE_OUTPUTS;
417         int nparms = ARRAY_SIZE(output_parms);
418         int nattrs = nouts * nparms + 1;
419
420         attrs = devm_kcalloc(gth->dev, nattrs, sizeof(void *), GFP_KERNEL);
421         if (!attrs)
422                 return -ENOMEM;
423
424         out_attrs = devm_kcalloc(gth->dev, nattrs,
425                                  sizeof(struct output_attribute),
426                                  GFP_KERNEL);
427         if (!out_attrs)
428                 return -ENOMEM;
429
430         for (i = 0; i < nouts; i++) {
431                 for (j = 0; j < nparms; j++) {
432                         unsigned int idx = i * nparms + j;
433                         char *name;
434
435                         name = devm_kasprintf(gth->dev, GFP_KERNEL, "%d_%s", i,
436                                               output_parms[j].name);
437                         if (!name)
438                                 return -ENOMEM;
439
440                         out_attrs[idx].attr.attr.name = name;
441
442                         if (output_parms[j].readable) {
443                                 out_attrs[idx].attr.attr.mode |= S_IRUGO;
444                                 out_attrs[idx].attr.show = output_attr_show;
445                         }
446
447                         if (output_parms[j].writable) {
448                                 out_attrs[idx].attr.attr.mode |= S_IWUSR;
449                                 out_attrs[idx].attr.store = output_attr_store;
450                         }
451
452                         sysfs_attr_init(&out_attrs[idx].attr.attr);
453                         attrs[idx] = &out_attrs[idx].attr.attr;
454
455                         out_attrs[idx].gth = gth;
456                         out_attrs[idx].port = i;
457                         out_attrs[idx].parm = j;
458                 }
459         }
460
461         gth->output_group.name  = "outputs";
462         gth->output_group.attrs = attrs;
463
464         return sysfs_create_group(&gth->dev->kobj, &gth->output_group);
465 }
466
467 /**
468  * intel_th_gth_disable() - enable tracing to an output device
469  * @thdev:      GTH device
470  * @output:     output device's descriptor
471  *
472  * This will deconfigure all masters set to output to this device,
473  * disable tracing using force storeEn off signal and wait for the
474  * "pipeline empty" bit for corresponding output port.
475  */
476 static void intel_th_gth_disable(struct intel_th_device *thdev,
477                                  struct intel_th_output *output)
478 {
479         struct gth_device *gth = dev_get_drvdata(&thdev->dev);
480         unsigned long count;
481         int master;
482         u32 reg;
483
484         spin_lock(&gth->gth_lock);
485         output->active = false;
486
487         for_each_set_bit(master, gth->output[output->port].master,
488                          TH_CONFIGURABLE_MASTERS) {
489                 gth_master_set(gth, master, -1);
490         }
491         spin_unlock(&gth->gth_lock);
492
493         iowrite32(0, gth->base + REG_GTH_SCR);
494         iowrite32(0xfd, gth->base + REG_GTH_SCR2);
495
496         /* wait on pipeline empty for the given port */
497         for (reg = 0, count = GTH_PLE_WAITLOOP_DEPTH;
498              count && !(reg & BIT(output->port)); count--) {
499                 reg = ioread32(gth->base + REG_GTH_STAT);
500                 cpu_relax();
501         }
502
503         /* clear force capture done for next captures */
504         iowrite32(0xfc, gth->base + REG_GTH_SCR2);
505
506         if (!count)
507                 dev_dbg(&thdev->dev, "timeout waiting for GTH[%d] PLE\n",
508                         output->port);
509 }
510
511 /**
512  * intel_th_gth_enable() - enable tracing to an output device
513  * @thdev:      GTH device
514  * @output:     output device's descriptor
515  *
516  * This will configure all masters set to output to this device and
517  * enable tracing using force storeEn signal.
518  */
519 static void intel_th_gth_enable(struct intel_th_device *thdev,
520                                 struct intel_th_output *output)
521 {
522         struct gth_device *gth = dev_get_drvdata(&thdev->dev);
523         u32 scr = 0xfc0000;
524         int master;
525
526         spin_lock(&gth->gth_lock);
527         for_each_set_bit(master, gth->output[output->port].master,
528                          TH_CONFIGURABLE_MASTERS + 1) {
529                 gth_master_set(gth, master, output->port);
530         }
531
532         if (output->multiblock)
533                 scr |= 0xff;
534
535         output->active = true;
536         spin_unlock(&gth->gth_lock);
537
538         iowrite32(scr, gth->base + REG_GTH_SCR);
539         iowrite32(0, gth->base + REG_GTH_SCR2);
540 }
541
542 /**
543  * intel_th_gth_assign() - assign output device to a GTH output port
544  * @thdev:      GTH device
545  * @othdev:     output device
546  *
547  * This will match a given output device parameters against present
548  * output ports on the GTH and fill out relevant bits in output device's
549  * descriptor.
550  *
551  * Return:      0 on success, -errno on error.
552  */
553 static int intel_th_gth_assign(struct intel_th_device *thdev,
554                                struct intel_th_device *othdev)
555 {
556         struct gth_device *gth = dev_get_drvdata(&thdev->dev);
557         int i, id;
558
559         if (othdev->type != INTEL_TH_OUTPUT)
560                 return -EINVAL;
561
562         for (i = 0, id = 0; i < TH_POSSIBLE_OUTPUTS; i++) {
563                 if (gth->output[i].port_type != othdev->output.type)
564                         continue;
565
566                 if (othdev->id == -1 || othdev->id == id)
567                         goto found;
568
569                 id++;
570         }
571
572         return -ENOENT;
573
574 found:
575         spin_lock(&gth->gth_lock);
576         othdev->output.port = i;
577         othdev->output.active = false;
578         gth->output[i].output = &othdev->output;
579         spin_unlock(&gth->gth_lock);
580
581         return 0;
582 }
583
584 /**
585  * intel_th_gth_unassign() - deassociate an output device from its output port
586  * @thdev:      GTH device
587  * @othdev:     output device
588  */
589 static void intel_th_gth_unassign(struct intel_th_device *thdev,
590                                   struct intel_th_device *othdev)
591 {
592         struct gth_device *gth = dev_get_drvdata(&thdev->dev);
593         int port = othdev->output.port;
594
595         spin_lock(&gth->gth_lock);
596         othdev->output.port = -1;
597         othdev->output.active = false;
598         gth->output[port].output = NULL;
599         spin_unlock(&gth->gth_lock);
600 }
601
602 static int
603 intel_th_gth_set_output(struct intel_th_device *thdev, unsigned int master)
604 {
605         struct gth_device *gth = dev_get_drvdata(&thdev->dev);
606         int port = 0; /* FIXME: make default output configurable */
607
608         /*
609          * everything above TH_CONFIGURABLE_MASTERS is controlled by the
610          * same register
611          */
612         if (master > TH_CONFIGURABLE_MASTERS)
613                 master = TH_CONFIGURABLE_MASTERS;
614
615         spin_lock(&gth->gth_lock);
616         if (gth->master[master] == -1) {
617                 set_bit(master, gth->output[port].master);
618                 gth->master[master] = port;
619         }
620         spin_unlock(&gth->gth_lock);
621
622         return 0;
623 }
624
625 static int intel_th_gth_probe(struct intel_th_device *thdev)
626 {
627         struct device *dev = &thdev->dev;
628         struct gth_device *gth;
629         struct resource *res;
630         void __iomem *base;
631         int i, ret;
632
633         res = intel_th_device_get_resource(thdev, IORESOURCE_MEM, 0);
634         if (!res)
635                 return -ENODEV;
636
637         base = devm_ioremap(dev, res->start, resource_size(res));
638         if (!base)
639                 return -ENOMEM;
640
641         gth = devm_kzalloc(dev, sizeof(*gth), GFP_KERNEL);
642         if (!gth)
643                 return -ENOMEM;
644
645         gth->dev = dev;
646         gth->base = base;
647         spin_lock_init(&gth->gth_lock);
648
649         ret = intel_th_gth_reset(gth);
650         if (ret)
651                 return ret;
652
653         for (i = 0; i < TH_CONFIGURABLE_MASTERS + 1; i++)
654                 gth->master[i] = -1;
655
656         for (i = 0; i < TH_POSSIBLE_OUTPUTS; i++) {
657                 gth->output[i].gth = gth;
658                 gth->output[i].index = i;
659                 gth->output[i].port_type =
660                         gth_output_parm_get(gth, i, TH_OUTPUT_PARM(port));
661         }
662
663         if (intel_th_output_attributes(gth) ||
664             intel_th_master_attributes(gth)) {
665                 pr_warn("Can't initialize sysfs attributes\n");
666
667                 if (gth->output_group.attrs)
668                         sysfs_remove_group(&gth->dev->kobj, &gth->output_group);
669                 return -ENOMEM;
670         }
671
672         dev_set_drvdata(dev, gth);
673
674         return 0;
675 }
676
677 static void intel_th_gth_remove(struct intel_th_device *thdev)
678 {
679         struct gth_device *gth = dev_get_drvdata(&thdev->dev);
680
681         sysfs_remove_group(&gth->dev->kobj, &gth->output_group);
682         sysfs_remove_group(&gth->dev->kobj, &gth->master_group);
683 }
684
685 static struct intel_th_driver intel_th_gth_driver = {
686         .probe          = intel_th_gth_probe,
687         .remove         = intel_th_gth_remove,
688         .assign         = intel_th_gth_assign,
689         .unassign       = intel_th_gth_unassign,
690         .set_output     = intel_th_gth_set_output,
691         .enable         = intel_th_gth_enable,
692         .disable        = intel_th_gth_disable,
693         .driver = {
694                 .name   = "gth",
695                 .owner  = THIS_MODULE,
696         },
697 };
698
699 module_driver(intel_th_gth_driver,
700               intel_th_driver_register,
701               intel_th_driver_unregister);
702
703 MODULE_ALIAS("intel_th_switch");
704 MODULE_LICENSE("GPL v2");
705 MODULE_DESCRIPTION("Intel(R) Trace Hub Global Trace Hub driver");
706 MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@linux.intel.com>");