Lines Matching +full:coresight +full:- +full:tmc
1 // SPDX-License-Identifier: GPL-2.0
9 #include <linux/coresight.h>
12 #include "coresight-priv.h"
13 #include "coresight-tmc.h"
14 #include "coresight-etm-perf.h"
23 CS_UNLOCK(drvdata->base); in __tmc_etb_enable_hw()
28 dev_err(&drvdata->csdev->dev, in __tmc_etb_enable_hw()
29 "Failed to enable: TMC not ready\n"); in __tmc_etb_enable_hw()
30 CS_LOCK(drvdata->base); in __tmc_etb_enable_hw()
34 writel_relaxed(TMC_MODE_CIRCULAR_BUFFER, drvdata->base + TMC_MODE); in __tmc_etb_enable_hw()
38 drvdata->base + TMC_FFCR); in __tmc_etb_enable_hw()
40 writel_relaxed(drvdata->trigger_cntr, drvdata->base + TMC_TRG); in __tmc_etb_enable_hw()
43 CS_LOCK(drvdata->base); in __tmc_etb_enable_hw()
49 int rc = coresight_claim_device(drvdata->csdev); in tmc_etb_enable_hw()
56 coresight_disclaim_device(drvdata->csdev); in tmc_etb_enable_hw()
66 lost = readl_relaxed(drvdata->base + TMC_STS) & TMC_STS_FULL; in tmc_etb_dump_hw()
67 bufp = drvdata->buf; in tmc_etb_dump_hw()
68 drvdata->len = 0; in tmc_etb_dump_hw()
70 read_data = readl_relaxed(drvdata->base + TMC_RRD); in tmc_etb_dump_hw()
75 drvdata->len += 4; in tmc_etb_dump_hw()
79 coresight_insert_barrier_packet(drvdata->buf); in tmc_etb_dump_hw()
85 CS_UNLOCK(drvdata->base); in __tmc_etb_disable_hw()
90 * read before the TMC is disabled. in __tmc_etb_disable_hw()
92 if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) in __tmc_etb_disable_hw()
96 CS_LOCK(drvdata->base); in __tmc_etb_disable_hw()
102 coresight_disclaim_device(drvdata->csdev); in tmc_etb_disable_hw()
109 CS_UNLOCK(drvdata->base); in __tmc_etf_enable_hw()
114 dev_err(&drvdata->csdev->dev, in __tmc_etf_enable_hw()
115 "Failed to enable : TMC is not ready\n"); in __tmc_etf_enable_hw()
116 CS_LOCK(drvdata->base); in __tmc_etf_enable_hw()
120 writel_relaxed(TMC_MODE_HARDWARE_FIFO, drvdata->base + TMC_MODE); in __tmc_etf_enable_hw()
122 drvdata->base + TMC_FFCR); in __tmc_etf_enable_hw()
123 writel_relaxed(0x0, drvdata->base + TMC_BUFWM); in __tmc_etf_enable_hw()
126 CS_LOCK(drvdata->base); in __tmc_etf_enable_hw()
132 int rc = coresight_claim_device(drvdata->csdev); in tmc_etf_enable_hw()
139 coresight_disclaim_device(drvdata->csdev); in tmc_etf_enable_hw()
145 struct coresight_device *csdev = drvdata->csdev; in tmc_etf_disable_hw()
147 CS_UNLOCK(drvdata->base); in tmc_etf_disable_hw()
152 CS_LOCK(drvdata->base); in tmc_etf_disable_hw()
166 if (pos + actual > drvdata->len) in tmc_etb_get_sysfs_trace()
167 actual = drvdata->len - pos; in tmc_etb_get_sysfs_trace()
169 *bufpp = drvdata->buf + pos; in tmc_etb_get_sysfs_trace()
179 struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); in tmc_enable_etf_sink_sysfs()
185 spin_lock_irqsave(&drvdata->spinlock, flags); in tmc_enable_etf_sink_sysfs()
186 if (!drvdata->buf) { in tmc_enable_etf_sink_sysfs()
187 spin_unlock_irqrestore(&drvdata->spinlock, flags); in tmc_enable_etf_sink_sysfs()
190 buf = kzalloc(drvdata->size, GFP_KERNEL); in tmc_enable_etf_sink_sysfs()
192 return -ENOMEM; in tmc_enable_etf_sink_sysfs()
195 spin_lock_irqsave(&drvdata->spinlock, flags); in tmc_enable_etf_sink_sysfs()
198 if (drvdata->reading) { in tmc_enable_etf_sink_sysfs()
199 ret = -EBUSY; in tmc_enable_etf_sink_sysfs()
209 csdev->refcnt++; in tmc_enable_etf_sink_sysfs()
215 * trace run but wasn't read. If so simply zero-out the memory. in tmc_enable_etf_sink_sysfs()
222 if (drvdata->buf) { in tmc_enable_etf_sink_sysfs()
223 memset(drvdata->buf, 0, drvdata->size); in tmc_enable_etf_sink_sysfs()
226 drvdata->buf = buf; in tmc_enable_etf_sink_sysfs()
232 csdev->refcnt++; in tmc_enable_etf_sink_sysfs()
238 spin_unlock_irqrestore(&drvdata->spinlock, flags); in tmc_enable_etf_sink_sysfs()
252 struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); in tmc_enable_etf_sink_perf()
256 spin_lock_irqsave(&drvdata->spinlock, flags); in tmc_enable_etf_sink_perf()
258 ret = -EINVAL; in tmc_enable_etf_sink_perf()
259 if (drvdata->reading) in tmc_enable_etf_sink_perf()
266 ret = -EBUSY; in tmc_enable_etf_sink_perf()
271 pid = buf->pid; in tmc_enable_etf_sink_perf()
273 if (drvdata->pid != -1 && drvdata->pid != pid) { in tmc_enable_etf_sink_perf()
274 ret = -EBUSY; in tmc_enable_etf_sink_perf()
286 if (drvdata->pid == pid) { in tmc_enable_etf_sink_perf()
287 csdev->refcnt++; in tmc_enable_etf_sink_perf()
294 drvdata->pid = pid; in tmc_enable_etf_sink_perf()
296 csdev->refcnt++; in tmc_enable_etf_sink_perf()
299 spin_unlock_irqrestore(&drvdata->spinlock, flags); in tmc_enable_etf_sink_perf()
318 ret = -EINVAL; in tmc_enable_etf_sink()
325 dev_dbg(&csdev->dev, "TMC-ETB/ETF enabled\n"); in tmc_enable_etf_sink()
332 struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); in tmc_disable_etf_sink()
334 spin_lock_irqsave(&drvdata->spinlock, flags); in tmc_disable_etf_sink()
336 if (drvdata->reading) { in tmc_disable_etf_sink()
337 spin_unlock_irqrestore(&drvdata->spinlock, flags); in tmc_disable_etf_sink()
338 return -EBUSY; in tmc_disable_etf_sink()
341 csdev->refcnt--; in tmc_disable_etf_sink()
342 if (csdev->refcnt) { in tmc_disable_etf_sink()
343 spin_unlock_irqrestore(&drvdata->spinlock, flags); in tmc_disable_etf_sink()
344 return -EBUSY; in tmc_disable_etf_sink()
351 drvdata->pid = -1; in tmc_disable_etf_sink()
354 spin_unlock_irqrestore(&drvdata->spinlock, flags); in tmc_disable_etf_sink()
356 dev_dbg(&csdev->dev, "TMC-ETB/ETF disabled\n"); in tmc_disable_etf_sink()
366 struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); in tmc_enable_etf_link()
369 spin_lock_irqsave(&drvdata->spinlock, flags); in tmc_enable_etf_link()
370 if (drvdata->reading) { in tmc_enable_etf_link()
371 spin_unlock_irqrestore(&drvdata->spinlock, flags); in tmc_enable_etf_link()
372 return -EBUSY; in tmc_enable_etf_link()
375 if (csdev->refcnt == 0) { in tmc_enable_etf_link()
383 csdev->refcnt++; in tmc_enable_etf_link()
384 spin_unlock_irqrestore(&drvdata->spinlock, flags); in tmc_enable_etf_link()
387 dev_dbg(&csdev->dev, "TMC-ETF enabled\n"); in tmc_enable_etf_link()
396 struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); in tmc_disable_etf_link()
399 spin_lock_irqsave(&drvdata->spinlock, flags); in tmc_disable_etf_link()
400 if (drvdata->reading) { in tmc_disable_etf_link()
401 spin_unlock_irqrestore(&drvdata->spinlock, flags); in tmc_disable_etf_link()
405 csdev->refcnt--; in tmc_disable_etf_link()
406 if (csdev->refcnt == 0) { in tmc_disable_etf_link()
411 spin_unlock_irqrestore(&drvdata->spinlock, flags); in tmc_disable_etf_link()
414 dev_dbg(&csdev->dev, "TMC-ETF disabled\n"); in tmc_disable_etf_link()
424 node = (event->cpu == -1) ? NUMA_NO_NODE : cpu_to_node(event->cpu); in tmc_alloc_etf_buffer()
431 buf->pid = task_pid_nr(event->owner); in tmc_alloc_etf_buffer()
432 buf->snapshot = overwrite; in tmc_alloc_etf_buffer()
433 buf->nr_pages = nr_pages; in tmc_alloc_etf_buffer()
434 buf->data_pages = pages; in tmc_alloc_etf_buffer()
454 return -EINVAL; in tmc_set_etf_buffer()
457 head = handle->head & (((unsigned long)buf->nr_pages << PAGE_SHIFT) - 1); in tmc_set_etf_buffer()
460 buf->cur = head / PAGE_SIZE; in tmc_set_etf_buffer()
463 buf->offset = head % PAGE_SIZE; in tmc_set_etf_buffer()
465 local_set(&buf->data_size, 0); in tmc_set_etf_buffer()
482 struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); in tmc_update_etf_buffer()
491 spin_lock_irqsave(&drvdata->spinlock, flags); in tmc_update_etf_buffer()
494 if (csdev->refcnt != 1) in tmc_update_etf_buffer()
497 CS_UNLOCK(drvdata->base); in tmc_update_etf_buffer()
508 status = readl_relaxed(drvdata->base + TMC_STS); in tmc_update_etf_buffer()
511 to_read = drvdata->size; in tmc_update_etf_buffer()
513 to_read = CIRC_CNT(write_ptr, read_ptr, drvdata->size); in tmc_update_etf_buffer()
517 * The TMC RAM buffer may be bigger than the space available in the in tmc_update_etf_buffer()
518 * perf ring buffer (handle->size). If so advance the RRP so that we in tmc_update_etf_buffer()
523 if (!buf->snapshot && to_read > handle->size) { in tmc_update_etf_buffer()
530 to_read = handle->size & mask; in tmc_update_etf_buffer()
532 read_ptr = (write_ptr + drvdata->size) - to_read; in tmc_update_etf_buffer()
534 if (read_ptr > (drvdata->size - 1)) in tmc_update_etf_buffer()
535 read_ptr -= drvdata->size; in tmc_update_etf_buffer()
544 * prevents the event from being re-enabled by the perf core, in tmc_update_etf_buffer()
547 if (!buf->snapshot && lost) in tmc_update_etf_buffer()
550 cur = buf->cur; in tmc_update_etf_buffer()
551 offset = buf->offset; in tmc_update_etf_buffer()
556 buf_ptr = buf->data_pages[cur] + offset; in tmc_update_etf_buffer()
557 *buf_ptr = readl_relaxed(drvdata->base + TMC_RRD); in tmc_update_etf_buffer()
569 cur &= buf->nr_pages - 1; in tmc_update_etf_buffer()
578 if (buf->snapshot) in tmc_update_etf_buffer()
579 handle->head += to_read; in tmc_update_etf_buffer()
586 CS_LOCK(drvdata->base); in tmc_update_etf_buffer()
588 spin_unlock_irqrestore(&drvdata->spinlock, flags); in tmc_update_etf_buffer()
622 if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETB && in tmc_read_prepare_etb()
623 drvdata->config_type != TMC_CONFIG_TYPE_ETF)) in tmc_read_prepare_etb()
624 return -EINVAL; in tmc_read_prepare_etb()
626 spin_lock_irqsave(&drvdata->spinlock, flags); in tmc_read_prepare_etb()
628 if (drvdata->reading) { in tmc_read_prepare_etb()
629 ret = -EBUSY; in tmc_read_prepare_etb()
634 if (coresight_get_mode(drvdata->csdev) == CS_MODE_PERF) { in tmc_read_prepare_etb()
635 ret = -EINVAL; in tmc_read_prepare_etb()
640 if (drvdata->buf == NULL) { in tmc_read_prepare_etb()
641 ret = -EINVAL; in tmc_read_prepare_etb()
645 /* Disable the TMC if need be */ in tmc_read_prepare_etb()
646 if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) { in tmc_read_prepare_etb()
647 /* There is no point in reading a TMC in HW FIFO mode */ in tmc_read_prepare_etb()
648 mode = readl_relaxed(drvdata->base + TMC_MODE); in tmc_read_prepare_etb()
650 ret = -EINVAL; in tmc_read_prepare_etb()
656 drvdata->reading = true; in tmc_read_prepare_etb()
658 spin_unlock_irqrestore(&drvdata->spinlock, flags); in tmc_read_prepare_etb()
671 if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETB && in tmc_read_unprepare_etb()
672 drvdata->config_type != TMC_CONFIG_TYPE_ETF)) in tmc_read_unprepare_etb()
673 return -EINVAL; in tmc_read_unprepare_etb()
675 spin_lock_irqsave(&drvdata->spinlock, flags); in tmc_read_unprepare_etb()
677 /* Re-enable the TMC if need be */ in tmc_read_unprepare_etb()
678 if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) { in tmc_read_unprepare_etb()
679 /* There is no point in reading a TMC in HW FIFO mode */ in tmc_read_unprepare_etb()
680 mode = readl_relaxed(drvdata->base + TMC_MODE); in tmc_read_unprepare_etb()
682 spin_unlock_irqrestore(&drvdata->spinlock, flags); in tmc_read_unprepare_etb()
683 return -EINVAL; in tmc_read_unprepare_etb()
687 * buffer. As such zero-out the buffer so that we don't end in tmc_read_unprepare_etb()
693 memset(drvdata->buf, 0, drvdata->size); in tmc_read_unprepare_etb()
696 spin_unlock_irqrestore(&drvdata->spinlock, flags); in tmc_read_unprepare_etb()
704 buf = drvdata->buf; in tmc_read_unprepare_etb()
705 drvdata->buf = NULL; in tmc_read_unprepare_etb()
708 drvdata->reading = false; in tmc_read_unprepare_etb()
709 spin_unlock_irqrestore(&drvdata->spinlock, flags); in tmc_read_unprepare_etb()