| .. | .. |
|---|
| 308 | 308 | iowrite32(0, gth->base + REG_GTH_SCR); |
|---|
| 309 | 309 | iowrite32(0xfc, gth->base + REG_GTH_SCR2); |
|---|
| 310 | 310 | |
|---|
| 311 | + /* setup CTS for single trigger */ |
|---|
| 312 | + iowrite32(CTS_EVENT_ENABLE_IF_ANYTHING, gth->base + REG_CTS_C0S0_EN); |
|---|
| 313 | + iowrite32(CTS_ACTION_CONTROL_SET_STATE(CTS_STATE_IDLE) | |
|---|
| 314 | + CTS_ACTION_CONTROL_TRIGGER, gth->base + REG_CTS_C0S0_ACT); |
|---|
| 315 | + |
|---|
| 311 | 316 | return 0; |
|---|
| 312 | 317 | } |
|---|
| 313 | 318 | |
|---|
| .. | .. |
|---|
| 457 | 462 | } |
|---|
| 458 | 463 | |
|---|
| 459 | 464 | /** |
|---|
| 465 | + * intel_th_gth_stop() - stop tracing to an output device |
|---|
| 466 | + * @gth: GTH device |
|---|
| 467 | + * @output: output device's descriptor |
|---|
| 468 | + * @capture_done: set when no more traces will be captured |
|---|
| 469 | + * |
|---|
| 470 | + * This will stop tracing using force storeEn off signal and wait for the |
|---|
| 471 | + * pipelines to be empty for the corresponding output port. |
|---|
| 472 | + */ |
|---|
| 473 | +static void intel_th_gth_stop(struct gth_device *gth, |
|---|
| 474 | + struct intel_th_output *output, |
|---|
| 475 | + bool capture_done) |
|---|
| 476 | +{ |
|---|
| 477 | + struct intel_th_device *outdev = |
|---|
| 478 | + container_of(output, struct intel_th_device, output); |
|---|
| 479 | + struct intel_th_driver *outdrv = |
|---|
| 480 | + to_intel_th_driver(outdev->dev.driver); |
|---|
| 481 | + unsigned long count; |
|---|
| 482 | + u32 reg; |
|---|
| 483 | + u32 scr2 = 0xfc | (capture_done ? 1 : 0); |
|---|
| 484 | + |
|---|
| 485 | + iowrite32(0, gth->base + REG_GTH_SCR); |
|---|
| 486 | + iowrite32(scr2, gth->base + REG_GTH_SCR2); |
|---|
| 487 | + |
|---|
| 488 | + /* wait on pipeline empty for the given port */ |
|---|
| 489 | + for (reg = 0, count = GTH_PLE_WAITLOOP_DEPTH; |
|---|
| 490 | + count && !(reg & BIT(output->port)); count--) { |
|---|
| 491 | + reg = ioread32(gth->base + REG_GTH_STAT); |
|---|
| 492 | + cpu_relax(); |
|---|
| 493 | + } |
|---|
| 494 | + |
|---|
| 495 | + if (!count) |
|---|
| 496 | + dev_dbg(gth->dev, "timeout waiting for GTH[%d] PLE\n", |
|---|
| 497 | + output->port); |
|---|
| 498 | + |
|---|
| 499 | + /* wait on output piepline empty */ |
|---|
| 500 | + if (outdrv->wait_empty) |
|---|
| 501 | + outdrv->wait_empty(outdev); |
|---|
| 502 | + |
|---|
| 503 | + /* clear force capture done for next captures */ |
|---|
| 504 | + iowrite32(0xfc, gth->base + REG_GTH_SCR2); |
|---|
| 505 | +} |
|---|
| 506 | + |
|---|
| 507 | +/** |
|---|
| 508 | + * intel_th_gth_start() - start tracing to an output device |
|---|
| 509 | + * @gth: GTH device |
|---|
| 510 | + * @output: output device's descriptor |
|---|
| 511 | + * |
|---|
| 512 | + * This will start tracing using force storeEn signal. |
|---|
| 513 | + */ |
|---|
| 514 | +static void intel_th_gth_start(struct gth_device *gth, |
|---|
| 515 | + struct intel_th_output *output) |
|---|
| 516 | +{ |
|---|
| 517 | + u32 scr = 0xfc0000; |
|---|
| 518 | + |
|---|
| 519 | + if (output->multiblock) |
|---|
| 520 | + scr |= 0xff; |
|---|
| 521 | + |
|---|
| 522 | + iowrite32(scr, gth->base + REG_GTH_SCR); |
|---|
| 523 | + iowrite32(0, gth->base + REG_GTH_SCR2); |
|---|
| 524 | +} |
|---|
| 525 | + |
|---|
| 526 | +/** |
|---|
| 460 | 527 | * intel_th_gth_disable() - disable tracing to an output device |
|---|
| 461 | 528 | * @thdev: GTH device |
|---|
| 462 | 529 | * @output: output device's descriptor |
|---|
| .. | .. |
|---|
| 469 | 536 | struct intel_th_output *output) |
|---|
| 470 | 537 | { |
|---|
| 471 | 538 | struct gth_device *gth = dev_get_drvdata(&thdev->dev); |
|---|
| 472 | | - unsigned long count; |
|---|
| 473 | 539 | int master; |
|---|
| 474 | 540 | u32 reg; |
|---|
| 475 | 541 | |
|---|
| .. | .. |
|---|
| 482 | 548 | } |
|---|
| 483 | 549 | spin_unlock(>h->gth_lock); |
|---|
| 484 | 550 | |
|---|
| 485 | | - iowrite32(0, gth->base + REG_GTH_SCR); |
|---|
| 486 | | - iowrite32(0xfd, gth->base + REG_GTH_SCR2); |
|---|
| 487 | | - |
|---|
| 488 | | - /* wait on pipeline empty for the given port */ |
|---|
| 489 | | - for (reg = 0, count = GTH_PLE_WAITLOOP_DEPTH; |
|---|
| 490 | | - count && !(reg & BIT(output->port)); count--) { |
|---|
| 491 | | - reg = ioread32(gth->base + REG_GTH_STAT); |
|---|
| 492 | | - cpu_relax(); |
|---|
| 493 | | - } |
|---|
| 494 | | - |
|---|
| 495 | | - /* clear force capture done for next captures */ |
|---|
| 496 | | - iowrite32(0xfc, gth->base + REG_GTH_SCR2); |
|---|
| 497 | | - |
|---|
| 498 | | - if (!count) |
|---|
| 499 | | - dev_dbg(&thdev->dev, "timeout waiting for GTH[%d] PLE\n", |
|---|
| 500 | | - output->port); |
|---|
| 551 | + intel_th_gth_stop(gth, output, true); |
|---|
| 501 | 552 | |
|---|
| 502 | 553 | reg = ioread32(gth->base + REG_GTH_SCRPD0); |
|---|
| 503 | 554 | reg &= ~output->scratchpad; |
|---|
| .. | .. |
|---|
| 541 | 592 | { |
|---|
| 542 | 593 | struct gth_device *gth = dev_get_drvdata(&thdev->dev); |
|---|
| 543 | 594 | struct intel_th *th = to_intel_th(thdev); |
|---|
| 544 | | - u32 scr = 0xfc0000, scrpd; |
|---|
| 545 | 595 | int master; |
|---|
| 596 | + u32 scrpd; |
|---|
| 546 | 597 | |
|---|
| 547 | 598 | spin_lock(>h->gth_lock); |
|---|
| 548 | 599 | for_each_set_bit(master, gth->output[output->port].master, |
|---|
| 549 | 600 | TH_CONFIGURABLE_MASTERS + 1) { |
|---|
| 550 | 601 | gth_master_set(gth, master, output->port); |
|---|
| 551 | 602 | } |
|---|
| 552 | | - |
|---|
| 553 | | - if (output->multiblock) |
|---|
| 554 | | - scr |= 0xff; |
|---|
| 555 | 603 | |
|---|
| 556 | 604 | output->active = true; |
|---|
| 557 | 605 | spin_unlock(>h->gth_lock); |
|---|
| .. | .. |
|---|
| 563 | 611 | scrpd |= output->scratchpad; |
|---|
| 564 | 612 | iowrite32(scrpd, gth->base + REG_GTH_SCRPD0); |
|---|
| 565 | 613 | |
|---|
| 566 | | - iowrite32(scr, gth->base + REG_GTH_SCR); |
|---|
| 567 | | - iowrite32(0, gth->base + REG_GTH_SCR2); |
|---|
| 614 | + intel_th_gth_start(gth, output); |
|---|
| 615 | +} |
|---|
| 616 | + |
|---|
| 617 | +/** |
|---|
| 618 | + * intel_th_gth_switch() - execute a switch sequence |
|---|
| 619 | + * @thdev: GTH device |
|---|
| 620 | + * @output: output device's descriptor |
|---|
| 621 | + * |
|---|
| 622 | + * This will execute a switch sequence that will trigger a switch window |
|---|
| 623 | + * when tracing to MSC in multi-block mode. |
|---|
| 624 | + */ |
|---|
| 625 | +static void intel_th_gth_switch(struct intel_th_device *thdev, |
|---|
| 626 | + struct intel_th_output *output) |
|---|
| 627 | +{ |
|---|
| 628 | + struct gth_device *gth = dev_get_drvdata(&thdev->dev); |
|---|
| 629 | + unsigned long count; |
|---|
| 630 | + u32 reg; |
|---|
| 631 | + |
|---|
| 632 | + /* trigger */ |
|---|
| 633 | + iowrite32(0, gth->base + REG_CTS_CTL); |
|---|
| 634 | + iowrite32(CTS_CTL_SEQUENCER_ENABLE, gth->base + REG_CTS_CTL); |
|---|
| 635 | + /* wait on trigger status */ |
|---|
| 636 | + for (reg = 0, count = CTS_TRIG_WAITLOOP_DEPTH; |
|---|
| 637 | + count && !(reg & BIT(4)); count--) { |
|---|
| 638 | + reg = ioread32(gth->base + REG_CTS_STAT); |
|---|
| 639 | + cpu_relax(); |
|---|
| 640 | + } |
|---|
| 641 | + if (!count) |
|---|
| 642 | + dev_dbg(&thdev->dev, "timeout waiting for CTS Trigger\n"); |
|---|
| 643 | + |
|---|
| 644 | + /* De-assert the trigger */ |
|---|
| 645 | + iowrite32(0, gth->base + REG_CTS_CTL); |
|---|
| 646 | + |
|---|
| 647 | + intel_th_gth_stop(gth, output, false); |
|---|
| 648 | + intel_th_gth_start(gth, output); |
|---|
| 568 | 649 | } |
|---|
| 569 | 650 | |
|---|
| 570 | 651 | /** |
|---|
| .. | .. |
|---|
| 751 | 832 | .set_output = intel_th_gth_set_output, |
|---|
| 752 | 833 | .prepare = intel_th_gth_prepare, |
|---|
| 753 | 834 | .enable = intel_th_gth_enable, |
|---|
| 835 | + .trig_switch = intel_th_gth_switch, |
|---|
| 754 | 836 | .disable = intel_th_gth_disable, |
|---|
| 755 | 837 | .driver = { |
|---|
| 756 | 838 | .name = "gth", |
|---|