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 #include <linux/pm_runtime.h> 26 27 #include "intel_th.h" 28 #include "gth.h" 29 30 struct gth_device; 31 32 /** 33 * struct gth_output - GTH view on an output port 34 * @gth: backlink to the GTH device 35 * @output: link to output device's output descriptor 36 * @index: output port number 37 * @port_type: one of GTH_* port type values 38 * @master: bitmap of masters configured for this output 39 */ 40 struct gth_output { 41 struct gth_device *gth; 42 struct intel_th_output *output; 43 unsigned int index; 44 unsigned int port_type; 45 DECLARE_BITMAP(master, TH_CONFIGURABLE_MASTERS + 1); 46 }; 47 48 /** 49 * struct gth_device - GTH device 50 * @dev: driver core's device 51 * @base: register window base address 52 * @output_group: attributes describing output ports 53 * @master_group: attributes describing master assignments 54 * @output: output ports 55 * @master: master/output port assignments 56 * @gth_lock: serializes accesses to GTH bits 57 */ 58 struct gth_device { 59 struct device *dev; 60 void __iomem *base; 61 62 struct attribute_group output_group; 63 struct attribute_group master_group; 64 struct gth_output output[TH_POSSIBLE_OUTPUTS]; 65 signed char master[TH_CONFIGURABLE_MASTERS + 1]; 66 spinlock_t gth_lock; 67 }; 68 69 static void gth_output_set(struct gth_device *gth, int port, 70 unsigned int config) 71 { 72 unsigned long reg = port & 4 ? REG_GTH_GTHOPT1 : REG_GTH_GTHOPT0; 73 u32 val; 74 int shift = (port & 3) * 8; 75 76 val = ioread32(gth->base + reg); 77 val &= ~(0xff << shift); 78 val |= config << shift; 79 iowrite32(val, gth->base + reg); 80 } 81 82 static unsigned int gth_output_get(struct gth_device *gth, int port) 83 { 84 unsigned long reg = port & 4 ? REG_GTH_GTHOPT1 : REG_GTH_GTHOPT0; 85 u32 val; 86 int shift = (port & 3) * 8; 87 88 val = ioread32(gth->base + reg); 89 val &= 0xff << shift; 90 val >>= shift; 91 92 return val; 93 } 94 95 static void gth_smcfreq_set(struct gth_device *gth, int port, 96 unsigned int freq) 97 { 98 unsigned long reg = REG_GTH_SMCR0 + ((port / 2) * 4); 99 int shift = (port & 1) * 16; 100 u32 val; 101 102 val = ioread32(gth->base + reg); 103 val &= ~(0xffff << shift); 104 val |= freq << shift; 105 iowrite32(val, gth->base + reg); 106 } 107 108 static unsigned int gth_smcfreq_get(struct gth_device *gth, int port) 109 { 110 unsigned long reg = REG_GTH_SMCR0 + ((port / 2) * 4); 111 int shift = (port & 1) * 16; 112 u32 val; 113 114 val = ioread32(gth->base + reg); 115 val &= 0xffff << shift; 116 val >>= shift; 117 118 return val; 119 } 120 121 /* 122 * "masters" attribute group 123 */ 124 125 struct master_attribute { 126 struct device_attribute attr; 127 struct gth_device *gth; 128 unsigned int master; 129 }; 130 131 static void 132 gth_master_set(struct gth_device *gth, unsigned int master, int port) 133 { 134 unsigned int reg = REG_GTH_SWDEST0 + ((master >> 1) & ~3u); 135 unsigned int shift = (master & 0x7) * 4; 136 u32 val; 137 138 if (master >= 256) { 139 reg = REG_GTH_GSWTDEST; 140 shift = 0; 141 } 142 143 val = ioread32(gth->base + reg); 144 val &= ~(0xf << shift); 145 if (port >= 0) 146 val |= (0x8 | port) << shift; 147 iowrite32(val, gth->base + reg); 148 } 149 150 static ssize_t master_attr_show(struct device *dev, 151 struct device_attribute *attr, 152 char *buf) 153 { 154 struct master_attribute *ma = 155 container_of(attr, struct master_attribute, attr); 156 struct gth_device *gth = ma->gth; 157 size_t count; 158 int port; 159 160 spin_lock(>h->gth_lock); 161 port = gth->master[ma->master]; 162 spin_unlock(>h->gth_lock); 163 164 if (port >= 0) 165 count = snprintf(buf, PAGE_SIZE, "%x\n", port); 166 else 167 count = snprintf(buf, PAGE_SIZE, "disabled\n"); 168 169 return count; 170 } 171 172 static ssize_t master_attr_store(struct device *dev, 173 struct device_attribute *attr, 174 const char *buf, size_t count) 175 { 176 struct master_attribute *ma = 177 container_of(attr, struct master_attribute, attr); 178 struct gth_device *gth = ma->gth; 179 int old_port, port; 180 181 if (kstrtoint(buf, 10, &port) < 0) 182 return -EINVAL; 183 184 if (port >= TH_POSSIBLE_OUTPUTS || port < -1) 185 return -EINVAL; 186 187 spin_lock(>h->gth_lock); 188 189 /* disconnect from the previous output port, if any */ 190 old_port = gth->master[ma->master]; 191 if (old_port >= 0) { 192 gth->master[ma->master] = -1; 193 clear_bit(ma->master, gth->output[old_port].master); 194 195 /* 196 * if the port is active, program this setting, 197 * implies that runtime PM is on 198 */ 199 if (gth->output[old_port].output->active) 200 gth_master_set(gth, ma->master, -1); 201 } 202 203 /* connect to the new output port, if any */ 204 if (port >= 0) { 205 /* check if there's a driver for this port */ 206 if (!gth->output[port].output) { 207 count = -ENODEV; 208 goto unlock; 209 } 210 211 set_bit(ma->master, gth->output[port].master); 212 213 /* if the port is active, program this setting, see above */ 214 if (gth->output[port].output->active) 215 gth_master_set(gth, ma->master, port); 216 } 217 218 gth->master[ma->master] = port; 219 220 unlock: 221 spin_unlock(>h->gth_lock); 222 223 return count; 224 } 225 226 struct output_attribute { 227 struct device_attribute attr; 228 struct gth_device *gth; 229 unsigned int port; 230 unsigned int parm; 231 }; 232 233 #define OUTPUT_PARM(_name, _mask, _r, _w, _what) \ 234 [TH_OUTPUT_PARM(_name)] = { .name = __stringify(_name), \ 235 .get = gth_ ## _what ## _get, \ 236 .set = gth_ ## _what ## _set, \ 237 .mask = (_mask), \ 238 .readable = (_r), \ 239 .writable = (_w) } 240 241 static const struct output_parm { 242 const char *name; 243 unsigned int (*get)(struct gth_device *gth, int port); 244 void (*set)(struct gth_device *gth, int port, 245 unsigned int val); 246 unsigned int mask; 247 unsigned int readable : 1, 248 writable : 1; 249 } output_parms[] = { 250 OUTPUT_PARM(port, 0x7, 1, 0, output), 251 OUTPUT_PARM(null, BIT(3), 1, 1, output), 252 OUTPUT_PARM(drop, BIT(4), 1, 1, output), 253 OUTPUT_PARM(reset, BIT(5), 1, 0, output), 254 OUTPUT_PARM(flush, BIT(7), 0, 1, output), 255 OUTPUT_PARM(smcfreq, 0xffff, 1, 1, smcfreq), 256 }; 257 258 static void 259 gth_output_parm_set(struct gth_device *gth, int port, unsigned int parm, 260 unsigned int val) 261 { 262 unsigned int config = output_parms[parm].get(gth, port); 263 unsigned int mask = output_parms[parm].mask; 264 unsigned int shift = __ffs(mask); 265 266 config &= ~mask; 267 config |= (val << shift) & mask; 268 output_parms[parm].set(gth, port, config); 269 } 270 271 static unsigned int 272 gth_output_parm_get(struct gth_device *gth, int port, unsigned int parm) 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 >>= shift; 280 return config; 281 } 282 283 /* 284 * Reset outputs and sources 285 */ 286 static int intel_th_gth_reset(struct gth_device *gth) 287 { 288 u32 scratchpad; 289 int port, i; 290 291 scratchpad = ioread32(gth->base + REG_GTH_SCRPD0); 292 if (scratchpad & SCRPD_DEBUGGER_IN_USE) 293 return -EBUSY; 294 295 /* Always save/restore STH and TU registers in S0ix entry/exit */ 296 scratchpad |= SCRPD_STH_IS_ENABLED | SCRPD_TRIGGER_IS_ENABLED; 297 iowrite32(scratchpad, gth->base + REG_GTH_SCRPD0); 298 299 /* output ports */ 300 for (port = 0; port < 8; port++) { 301 if (gth_output_parm_get(gth, port, TH_OUTPUT_PARM(port)) == 302 GTH_NONE) 303 continue; 304 305 gth_output_set(gth, port, 0); 306 gth_smcfreq_set(gth, port, 16); 307 } 308 /* disable overrides */ 309 iowrite32(0, gth->base + REG_GTH_DESTOVR); 310 311 /* masters swdest_0~31 and gswdest */ 312 for (i = 0; i < 33; i++) 313 iowrite32(0, gth->base + REG_GTH_SWDEST0 + i * 4); 314 315 /* sources */ 316 iowrite32(0, gth->base + REG_GTH_SCR); 317 iowrite32(0xfc, gth->base + REG_GTH_SCR2); 318 319 return 0; 320 } 321 322 /* 323 * "outputs" attribute group 324 */ 325 326 static ssize_t output_attr_show(struct device *dev, 327 struct device_attribute *attr, 328 char *buf) 329 { 330 struct output_attribute *oa = 331 container_of(attr, struct output_attribute, attr); 332 struct gth_device *gth = oa->gth; 333 size_t count; 334 335 pm_runtime_get_sync(dev); 336 337 spin_lock(>h->gth_lock); 338 count = snprintf(buf, PAGE_SIZE, "%x\n", 339 gth_output_parm_get(gth, oa->port, oa->parm)); 340 spin_unlock(>h->gth_lock); 341 342 pm_runtime_put(dev); 343 344 return count; 345 } 346 347 static ssize_t output_attr_store(struct device *dev, 348 struct device_attribute *attr, 349 const char *buf, size_t count) 350 { 351 struct output_attribute *oa = 352 container_of(attr, struct output_attribute, attr); 353 struct gth_device *gth = oa->gth; 354 unsigned int config; 355 356 if (kstrtouint(buf, 16, &config) < 0) 357 return -EINVAL; 358 359 pm_runtime_get_sync(dev); 360 361 spin_lock(>h->gth_lock); 362 gth_output_parm_set(gth, oa->port, oa->parm, config); 363 spin_unlock(>h->gth_lock); 364 365 pm_runtime_put(dev); 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(>h->dev->kobj, >h->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(>h->dev->kobj, >h->output_group); 465 } 466 467 /** 468 * intel_th_gth_disable() - disable 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(>h->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(>h->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 reg = ioread32(gth->base + REG_GTH_SCRPD0); 511 reg &= ~output->scratchpad; 512 iowrite32(reg, gth->base + REG_GTH_SCRPD0); 513 } 514 515 /** 516 * intel_th_gth_enable() - enable tracing to an output device 517 * @thdev: GTH device 518 * @output: output device's descriptor 519 * 520 * This will configure all masters set to output to this device and 521 * enable tracing using force storeEn signal. 522 */ 523 static void intel_th_gth_enable(struct intel_th_device *thdev, 524 struct intel_th_output *output) 525 { 526 struct gth_device *gth = dev_get_drvdata(&thdev->dev); 527 u32 scr = 0xfc0000, scrpd; 528 int master; 529 530 spin_lock(>h->gth_lock); 531 for_each_set_bit(master, gth->output[output->port].master, 532 TH_CONFIGURABLE_MASTERS + 1) { 533 gth_master_set(gth, master, output->port); 534 } 535 536 if (output->multiblock) 537 scr |= 0xff; 538 539 output->active = true; 540 spin_unlock(>h->gth_lock); 541 542 scrpd = ioread32(gth->base + REG_GTH_SCRPD0); 543 scrpd |= output->scratchpad; 544 iowrite32(scrpd, gth->base + REG_GTH_SCRPD0); 545 546 iowrite32(scr, gth->base + REG_GTH_SCR); 547 iowrite32(0, gth->base + REG_GTH_SCR2); 548 } 549 550 /** 551 * intel_th_gth_assign() - assign output device to a GTH output port 552 * @thdev: GTH device 553 * @othdev: output device 554 * 555 * This will match a given output device parameters against present 556 * output ports on the GTH and fill out relevant bits in output device's 557 * descriptor. 558 * 559 * Return: 0 on success, -errno on error. 560 */ 561 static int intel_th_gth_assign(struct intel_th_device *thdev, 562 struct intel_th_device *othdev) 563 { 564 struct gth_device *gth = dev_get_drvdata(&thdev->dev); 565 int i, id; 566 567 if (thdev->host_mode) 568 return -EBUSY; 569 570 if (othdev->type != INTEL_TH_OUTPUT) 571 return -EINVAL; 572 573 for (i = 0, id = 0; i < TH_POSSIBLE_OUTPUTS; i++) { 574 if (gth->output[i].port_type != othdev->output.type) 575 continue; 576 577 if (othdev->id == -1 || othdev->id == id) 578 goto found; 579 580 id++; 581 } 582 583 return -ENOENT; 584 585 found: 586 spin_lock(>h->gth_lock); 587 othdev->output.port = i; 588 othdev->output.active = false; 589 gth->output[i].output = &othdev->output; 590 spin_unlock(>h->gth_lock); 591 592 return 0; 593 } 594 595 /** 596 * intel_th_gth_unassign() - deassociate an output device from its output port 597 * @thdev: GTH device 598 * @othdev: output device 599 */ 600 static void intel_th_gth_unassign(struct intel_th_device *thdev, 601 struct intel_th_device *othdev) 602 { 603 struct gth_device *gth = dev_get_drvdata(&thdev->dev); 604 int port = othdev->output.port; 605 606 if (thdev->host_mode) 607 return; 608 609 spin_lock(>h->gth_lock); 610 othdev->output.port = -1; 611 othdev->output.active = false; 612 gth->output[port].output = NULL; 613 spin_unlock(>h->gth_lock); 614 } 615 616 static int 617 intel_th_gth_set_output(struct intel_th_device *thdev, unsigned int master) 618 { 619 struct gth_device *gth = dev_get_drvdata(&thdev->dev); 620 int port = 0; /* FIXME: make default output configurable */ 621 622 /* 623 * everything above TH_CONFIGURABLE_MASTERS is controlled by the 624 * same register 625 */ 626 if (master > TH_CONFIGURABLE_MASTERS) 627 master = TH_CONFIGURABLE_MASTERS; 628 629 spin_lock(>h->gth_lock); 630 if (gth->master[master] == -1) { 631 set_bit(master, gth->output[port].master); 632 gth->master[master] = port; 633 } 634 spin_unlock(>h->gth_lock); 635 636 return 0; 637 } 638 639 static int intel_th_gth_probe(struct intel_th_device *thdev) 640 { 641 struct device *dev = &thdev->dev; 642 struct gth_device *gth; 643 struct resource *res; 644 void __iomem *base; 645 int i, ret; 646 647 res = intel_th_device_get_resource(thdev, IORESOURCE_MEM, 0); 648 if (!res) 649 return -ENODEV; 650 651 base = devm_ioremap(dev, res->start, resource_size(res)); 652 if (!base) 653 return -ENOMEM; 654 655 gth = devm_kzalloc(dev, sizeof(*gth), GFP_KERNEL); 656 if (!gth) 657 return -ENOMEM; 658 659 gth->dev = dev; 660 gth->base = base; 661 spin_lock_init(>h->gth_lock); 662 663 /* 664 * Host mode can be signalled via SW means or via SCRPD_DEBUGGER_IN_USE 665 * bit. Either way, don't reset HW in this case, and don't export any 666 * capture configuration attributes. Also, refuse to assign output 667 * drivers to ports, see intel_th_gth_assign(). 668 */ 669 if (thdev->host_mode) 670 goto done; 671 672 ret = intel_th_gth_reset(gth); 673 if (ret) { 674 if (ret != -EBUSY) 675 return ret; 676 677 thdev->host_mode = true; 678 679 goto done; 680 } 681 682 for (i = 0; i < TH_CONFIGURABLE_MASTERS + 1; i++) 683 gth->master[i] = -1; 684 685 for (i = 0; i < TH_POSSIBLE_OUTPUTS; i++) { 686 gth->output[i].gth = gth; 687 gth->output[i].index = i; 688 gth->output[i].port_type = 689 gth_output_parm_get(gth, i, TH_OUTPUT_PARM(port)); 690 } 691 692 if (intel_th_output_attributes(gth) || 693 intel_th_master_attributes(gth)) { 694 pr_warn("Can't initialize sysfs attributes\n"); 695 696 if (gth->output_group.attrs) 697 sysfs_remove_group(>h->dev->kobj, >h->output_group); 698 return -ENOMEM; 699 } 700 701 done: 702 dev_set_drvdata(dev, gth); 703 704 return 0; 705 } 706 707 static void intel_th_gth_remove(struct intel_th_device *thdev) 708 { 709 struct gth_device *gth = dev_get_drvdata(&thdev->dev); 710 711 sysfs_remove_group(>h->dev->kobj, >h->output_group); 712 sysfs_remove_group(>h->dev->kobj, >h->master_group); 713 } 714 715 static struct intel_th_driver intel_th_gth_driver = { 716 .probe = intel_th_gth_probe, 717 .remove = intel_th_gth_remove, 718 .assign = intel_th_gth_assign, 719 .unassign = intel_th_gth_unassign, 720 .set_output = intel_th_gth_set_output, 721 .enable = intel_th_gth_enable, 722 .disable = intel_th_gth_disable, 723 .driver = { 724 .name = "gth", 725 .owner = THIS_MODULE, 726 }, 727 }; 728 729 module_driver(intel_th_gth_driver, 730 intel_th_driver_register, 731 intel_th_driver_unregister); 732 733 MODULE_ALIAS("intel_th_switch"); 734 MODULE_LICENSE("GPL v2"); 735 MODULE_DESCRIPTION("Intel(R) Trace Hub Global Trace Hub driver"); 736 MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@linux.intel.com>"); 737