Lines Matching +full:coresight +full:- +full:etb10

1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
5 * Description: CoreSight Embedded Trace Buffer driver
22 #include <linux/coresight.h>
30 #include "coresight-priv.h"
31 #include "coresight-etm-perf.h"
52 /* STS - 0x00C */
54 /* CTL - 0x020 */
56 /* FFCR - 0x304 */
69 * struct etb_drvdata - specifics associated to an ETB component
100 return readl_relaxed(drvdata->base + ETB_RAM_DEPTH_REG); in etb_get_buffer_depth()
108 CS_UNLOCK(drvdata->base); in __etb_enable_hw()
110 depth = drvdata->buffer_depth; in __etb_enable_hw()
112 writel_relaxed(0x0, drvdata->base + ETB_RAM_WRITE_POINTER); in __etb_enable_hw()
115 writel_relaxed(0x0, drvdata->base + ETB_RWD_REG); in __etb_enable_hw()
118 writel_relaxed(0x0, drvdata->base + ETB_RAM_WRITE_POINTER); in __etb_enable_hw()
120 writel_relaxed(0x0, drvdata->base + ETB_RAM_READ_POINTER); in __etb_enable_hw()
122 writel_relaxed(drvdata->trigger_cntr, drvdata->base + ETB_TRG); in __etb_enable_hw()
124 drvdata->base + ETB_FFCR); in __etb_enable_hw()
126 writel_relaxed(ETB_CTL_CAPT_EN, drvdata->base + ETB_CTL_REG); in __etb_enable_hw()
128 CS_LOCK(drvdata->base); in __etb_enable_hw()
133 int rc = coresight_claim_device(drvdata->csdev); in etb_enable_hw()
146 struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); in etb_enable_sysfs()
148 spin_lock_irqsave(&drvdata->spinlock, flags); in etb_enable_sysfs()
152 ret = -EBUSY; in etb_enable_sysfs()
164 csdev->refcnt++; in etb_enable_sysfs()
166 spin_unlock_irqrestore(&drvdata->spinlock, flags); in etb_enable_sysfs()
175 struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); in etb_enable_perf()
179 spin_lock_irqsave(&drvdata->spinlock, flags); in etb_enable_perf()
182 if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) { in etb_enable_perf()
183 ret = -EBUSY; in etb_enable_perf()
188 pid = buf->pid; in etb_enable_perf()
190 if (drvdata->pid != -1 && drvdata->pid != pid) { in etb_enable_perf()
191 ret = -EBUSY; in etb_enable_perf()
199 if (drvdata->pid == pid) { in etb_enable_perf()
200 csdev->refcnt++; in etb_enable_perf()
216 drvdata->pid = pid; in etb_enable_perf()
217 coresight_set_mode(drvdata->csdev, CS_MODE_PERF); in etb_enable_perf()
218 csdev->refcnt++; in etb_enable_perf()
222 spin_unlock_irqrestore(&drvdata->spinlock, flags); in etb_enable_perf()
239 ret = -EINVAL; in etb_enable()
246 dev_dbg(&csdev->dev, "ETB enabled\n"); in etb_enable()
253 struct device *dev = &drvdata->csdev->dev; in __etb_disable_hw()
254 struct csdev_access *csa = &drvdata->csdev->access; in __etb_disable_hw()
256 CS_UNLOCK(drvdata->base); in __etb_disable_hw()
258 ffcr = readl_relaxed(drvdata->base + ETB_FFCR); in __etb_disable_hw()
261 writel_relaxed(ffcr, drvdata->base + ETB_FFCR); in __etb_disable_hw()
264 writel_relaxed(ffcr, drvdata->base + ETB_FFCR); in __etb_disable_hw()
272 writel_relaxed(0x0, drvdata->base + ETB_CTL_REG); in __etb_disable_hw()
279 CS_LOCK(drvdata->base); in __etb_disable_hw()
290 struct device *dev = &drvdata->csdev->dev; in etb_dump_hw()
292 CS_UNLOCK(drvdata->base); in etb_dump_hw()
294 read_ptr = readl_relaxed(drvdata->base + ETB_RAM_READ_POINTER); in etb_dump_hw()
295 write_ptr = readl_relaxed(drvdata->base + ETB_RAM_WRITE_POINTER); in etb_dump_hw()
298 frame_endoff = ETB_FRAME_SIZE_WORDS - frame_off; in etb_dump_hw()
308 if ((readl_relaxed(drvdata->base + ETB_STATUS_REG) in etb_dump_hw()
310 writel_relaxed(0x0, drvdata->base + ETB_RAM_READ_POINTER); in etb_dump_hw()
312 writel_relaxed(write_ptr, drvdata->base + ETB_RAM_READ_POINTER); in etb_dump_hw()
316 depth = drvdata->buffer_depth; in etb_dump_hw()
317 buf_ptr = drvdata->buf; in etb_dump_hw()
319 read_data = readl_relaxed(drvdata->base + in etb_dump_hw()
326 coresight_insert_barrier_packet(drvdata->buf); in etb_dump_hw()
329 buf_ptr -= (frame_endoff * 4); in etb_dump_hw()
338 writel_relaxed(read_ptr, drvdata->base + ETB_RAM_READ_POINTER); in etb_dump_hw()
340 CS_LOCK(drvdata->base); in etb_dump_hw()
347 coresight_disclaim_device(drvdata->csdev); in etb_disable_hw()
352 struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); in etb_disable()
355 spin_lock_irqsave(&drvdata->spinlock, flags); in etb_disable()
357 csdev->refcnt--; in etb_disable()
358 if (csdev->refcnt) { in etb_disable()
359 spin_unlock_irqrestore(&drvdata->spinlock, flags); in etb_disable()
360 return -EBUSY; in etb_disable()
367 drvdata->pid = -1; in etb_disable()
369 spin_unlock_irqrestore(&drvdata->spinlock, flags); in etb_disable()
371 dev_dbg(&csdev->dev, "ETB disabled\n"); in etb_disable()
382 node = (event->cpu == -1) ? NUMA_NO_NODE : cpu_to_node(event->cpu); in etb_alloc_buffer()
388 buf->pid = task_pid_nr(event->owner); in etb_alloc_buffer()
389 buf->snapshot = overwrite; in etb_alloc_buffer()
390 buf->nr_pages = nr_pages; in etb_alloc_buffer()
391 buf->data_pages = pages; in etb_alloc_buffer()
411 return -EINVAL; in etb_set_buffer()
414 head = handle->head & ((buf->nr_pages << PAGE_SHIFT) - 1); in etb_set_buffer()
417 buf->cur = head / PAGE_SIZE; in etb_set_buffer()
420 buf->offset = head % PAGE_SIZE; in etb_set_buffer()
422 local_set(&buf->data_size, 0); in etb_set_buffer()
439 struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); in etb_update_buffer()
444 capacity = drvdata->buffer_depth * ETB_FRAME_SIZE_WORDS; in etb_update_buffer()
446 spin_lock_irqsave(&drvdata->spinlock, flags); in etb_update_buffer()
449 if (csdev->refcnt != 1) in etb_update_buffer()
453 CS_UNLOCK(drvdata->base); in etb_update_buffer()
456 read_ptr = readl_relaxed(drvdata->base + ETB_RAM_READ_POINTER); in etb_update_buffer()
457 write_ptr = readl_relaxed(drvdata->base + ETB_RAM_WRITE_POINTER); in etb_update_buffer()
465 dev_err(&csdev->dev, in etb_update_buffer()
469 write_ptr &= ~(ETB_FRAME_SIZE_WORDS - 1); in etb_update_buffer()
479 status = readl_relaxed(drvdata->base + ETB_STATUS_REG); in etb_update_buffer()
485 to_read = CIRC_CNT(write_ptr, read_ptr, drvdata->buffer_depth); in etb_update_buffer()
499 if (!buf->snapshot && to_read > handle->size) { in etb_update_buffer()
500 u32 mask = ~(ETB_FRAME_SIZE_WORDS - 1); in etb_update_buffer()
503 to_read = handle->size & mask; in etb_update_buffer()
508 read_ptr = (write_ptr + drvdata->buffer_depth) - in etb_update_buffer()
511 if (read_ptr > (drvdata->buffer_depth - 1)) in etb_update_buffer()
512 read_ptr -= drvdata->buffer_depth; in etb_update_buffer()
520 * prevents the event from being re-enabled by the perf core, in etb_update_buffer()
523 if (!buf->snapshot && lost) in etb_update_buffer()
527 writel_relaxed(read_ptr, drvdata->base + ETB_RAM_READ_POINTER); in etb_update_buffer()
529 cur = buf->cur; in etb_update_buffer()
530 offset = buf->offset; in etb_update_buffer()
534 buf_ptr = buf->data_pages[cur] + offset; in etb_update_buffer()
535 read_data = readl_relaxed(drvdata->base + in etb_update_buffer()
550 cur &= buf->nr_pages - 1; in etb_update_buffer()
555 writel_relaxed(0x0, drvdata->base + ETB_RAM_READ_POINTER); in etb_update_buffer()
556 writel_relaxed(0x0, drvdata->base + ETB_RAM_WRITE_POINTER); in etb_update_buffer()
563 if (buf->snapshot) in etb_update_buffer()
564 handle->head += to_read; in etb_update_buffer()
567 CS_LOCK(drvdata->base); in etb_update_buffer()
569 spin_unlock_irqrestore(&drvdata->spinlock, flags); in etb_update_buffer()
590 spin_lock_irqsave(&drvdata->spinlock, flags); in etb_dump()
591 if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) { in etb_dump()
596 spin_unlock_irqrestore(&drvdata->spinlock, flags); in etb_dump()
598 dev_dbg(&drvdata->csdev->dev, "ETB dumped\n"); in etb_dump()
603 struct etb_drvdata *drvdata = container_of(file->private_data, in etb_open()
606 if (local_cmpxchg(&drvdata->reading, 0, 1)) in etb_open()
607 return -EBUSY; in etb_open()
609 dev_dbg(&drvdata->csdev->dev, "%s: successfully opened\n", __func__); in etb_open()
617 struct etb_drvdata *drvdata = container_of(file->private_data, in etb_read()
619 struct device *dev = &drvdata->csdev->dev; in etb_read()
623 depth = drvdata->buffer_depth; in etb_read()
625 len = depth * 4 - *ppos; in etb_read()
627 if (copy_to_user(data, drvdata->buf + *ppos, len)) { in etb_read()
630 return -EFAULT; in etb_read()
636 __func__, len, (int)(depth * 4 - *ppos)); in etb_read()
642 struct etb_drvdata *drvdata = container_of(file->private_data, in etb_release()
644 local_set(&drvdata->reading, 0); in etb_release()
646 dev_dbg(&drvdata->csdev->dev, "%s: released\n", __func__); in etb_release()
672 struct etb_drvdata *drvdata = dev_get_drvdata(dev->parent); in trigger_cntr_show()
673 unsigned long val = drvdata->trigger_cntr; in trigger_cntr_show()
684 struct etb_drvdata *drvdata = dev_get_drvdata(dev->parent); in trigger_cntr_store()
690 drvdata->trigger_cntr = val; in trigger_cntr_store()
719 struct device *dev = &adev->dev; in etb_probe()
722 struct resource *res = &adev->res; in etb_probe()
727 return -ENOMEM; in etb_probe()
731 return -ENOMEM; in etb_probe()
733 drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */ in etb_probe()
734 if (!IS_ERR(drvdata->atclk)) { in etb_probe()
735 ret = clk_prepare_enable(drvdata->atclk); in etb_probe()
746 drvdata->base = base; in etb_probe()
749 spin_lock_init(&drvdata->spinlock); in etb_probe()
751 drvdata->buffer_depth = etb_get_buffer_depth(drvdata); in etb_probe()
753 if (drvdata->buffer_depth & 0x80000000) in etb_probe()
754 return -EINVAL; in etb_probe()
756 drvdata->buf = devm_kcalloc(dev, in etb_probe()
757 drvdata->buffer_depth, 4, GFP_KERNEL); in etb_probe()
758 if (!drvdata->buf) in etb_probe()
759 return -ENOMEM; in etb_probe()
762 drvdata->pid = -1; in etb_probe()
767 adev->dev.platform_data = pdata; in etb_probe()
775 drvdata->csdev = coresight_register(&desc); in etb_probe()
776 if (IS_ERR(drvdata->csdev)) in etb_probe()
777 return PTR_ERR(drvdata->csdev); in etb_probe()
779 drvdata->miscdev.name = desc.name; in etb_probe()
780 drvdata->miscdev.minor = MISC_DYNAMIC_MINOR; in etb_probe()
781 drvdata->miscdev.fops = &etb_fops; in etb_probe()
782 ret = misc_register(&drvdata->miscdev); in etb_probe()
786 pm_runtime_put(&adev->dev); in etb_probe()
790 coresight_unregister(drvdata->csdev); in etb_probe()
796 struct etb_drvdata *drvdata = dev_get_drvdata(&adev->dev); in etb_remove()
803 misc_deregister(&drvdata->miscdev); in etb_remove()
804 coresight_unregister(drvdata->csdev); in etb_remove()
812 if (drvdata && !IS_ERR(drvdata->atclk)) in etb_runtime_suspend()
813 clk_disable_unprepare(drvdata->atclk); in etb_runtime_suspend()
822 if (drvdata && !IS_ERR(drvdata->atclk)) in etb_runtime_resume()
823 clk_prepare_enable(drvdata->atclk); in etb_runtime_resume()
845 .name = "coresight-etb10",
859 MODULE_DESCRIPTION("Arm CoreSight Embedded Trace Buffer driver");