.. | .. |
---|
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", |
---|