hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/hwtracing/intel_th/gth.c
....@@ -308,6 +308,11 @@
308308 iowrite32(0, gth->base + REG_GTH_SCR);
309309 iowrite32(0xfc, gth->base + REG_GTH_SCR2);
310310
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
+
311316 return 0;
312317 }
313318
....@@ -457,6 +462,68 @@
457462 }
458463
459464 /**
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
+/**
460527 * intel_th_gth_disable() - disable tracing to an output device
461528 * @thdev: GTH device
462529 * @output: output device's descriptor
....@@ -469,7 +536,6 @@
469536 struct intel_th_output *output)
470537 {
471538 struct gth_device *gth = dev_get_drvdata(&thdev->dev);
472
- unsigned long count;
473539 int master;
474540 u32 reg;
475541
....@@ -482,22 +548,7 @@
482548 }
483549 spin_unlock(&gth->gth_lock);
484550
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);
501552
502553 reg = ioread32(gth->base + REG_GTH_SCRPD0);
503554 reg &= ~output->scratchpad;
....@@ -541,17 +592,14 @@
541592 {
542593 struct gth_device *gth = dev_get_drvdata(&thdev->dev);
543594 struct intel_th *th = to_intel_th(thdev);
544
- u32 scr = 0xfc0000, scrpd;
545595 int master;
596
+ u32 scrpd;
546597
547598 spin_lock(&gth->gth_lock);
548599 for_each_set_bit(master, gth->output[output->port].master,
549600 TH_CONFIGURABLE_MASTERS + 1) {
550601 gth_master_set(gth, master, output->port);
551602 }
552
-
553
- if (output->multiblock)
554
- scr |= 0xff;
555603
556604 output->active = true;
557605 spin_unlock(&gth->gth_lock);
....@@ -563,8 +611,41 @@
563611 scrpd |= output->scratchpad;
564612 iowrite32(scrpd, gth->base + REG_GTH_SCRPD0);
565613
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);
568649 }
569650
570651 /**
....@@ -751,6 +832,7 @@
751832 .set_output = intel_th_gth_set_output,
752833 .prepare = intel_th_gth_prepare,
753834 .enable = intel_th_gth_enable,
835
+ .trig_switch = intel_th_gth_switch,
754836 .disable = intel_th_gth_disable,
755837 .driver = {
756838 .name = "gth",