summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArto Merilainen <amerilainen@nvidia.com>2017-10-17 03:28:59 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2017-10-19 15:36:55 -0400
commit8d4623b8b28054dfad649b0ffd8aed8e2595de32 (patch)
treebdbf0eb632ffea7852a9924687584a42ccb7e43b
parent8ae44c1e585670db44aee55a1902320e0aa39546 (diff)
video: tegra: host: Add eventlib support
This change adds support for eventlib completion events. Eventlib is a library that is intended to interface with Tegra System Profiler to deliver information about e.g. task start and completion events. Bug 1996639 Change-Id: Ia5efcfb7ce54b7ee7822d6d5a153369b5a4ae535 Signed-off-by: Arto Merilainen <amerilainen@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1580285 Reviewed-by: Mikko Perttunen <mperttunen@nvidia.com>
-rw-r--r--drivers/video/tegra/host/bus_client.c73
-rw-r--r--include/linux/nvhost.h16
-rw-r--r--include/uapi/linux/nvhost_events.h71
3 files changed, 160 insertions, 0 deletions
diff --git a/drivers/video/tegra/host/bus_client.c b/drivers/video/tegra/host/bus_client.c
index 6f582680b..d9f94bde9 100644
--- a/drivers/video/tegra/host/bus_client.c
+++ b/drivers/video/tegra/host/bus_client.c
@@ -30,8 +30,10 @@
30#include <linux/dma-mapping.h> 30#include <linux/dma-mapping.h>
31#include <soc/tegra/chip-id.h> 31#include <soc/tegra/chip-id.h>
32#include <linux/anon_inodes.h> 32#include <linux/anon_inodes.h>
33#include <linux/crc32.h>
33 34
34#include <trace/events/nvhost.h> 35#include <trace/events/nvhost.h>
36#include <uapi/linux/nvhost_events.h>
35 37
36#include <linux/io.h> 38#include <linux/io.h>
37#include <linux/string.h> 39#include <linux/string.h>
@@ -39,6 +41,10 @@
39#include <linux/nvhost.h> 41#include <linux/nvhost.h>
40#include <linux/nvhost_ioctl.h> 42#include <linux/nvhost_ioctl.h>
41 43
44#ifdef CONFIG_EVENTLIB
45#include <linux/keventlib.h>
46#endif
47
42#include "debug.h" 48#include "debug.h"
43#include "bus_client.h" 49#include "bus_client.h"
44#include "dev.h" 50#include "dev.h"
@@ -1628,6 +1634,16 @@ int nvhost_client_device_init(struct platform_device *dev)
1628 if (pdata->scaling_init) 1634 if (pdata->scaling_init)
1629 pdata->scaling_init(dev); 1635 pdata->scaling_init(dev);
1630 1636
1637#ifdef CONFIG_EVENTLIB
1638 pdata->eventlib_id = keventlib_register(4 * PAGE_SIZE,
1639 dev_name(&dev->dev));
1640 if (pdata->eventlib_id < 0) {
1641 nvhost_warn(&dev->dev, "failed to register eventlib (err=%d)",
1642 pdata->eventlib_id);
1643 pdata->eventlib_id = 0;
1644 }
1645#endif
1646
1631 /* reset syncpoint values for this unit */ 1647 /* reset syncpoint values for this unit */
1632 err = nvhost_module_busy(nvhost_master->dev); 1648 err = nvhost_module_busy(nvhost_master->dev);
1633 if (err) 1649 if (err)
@@ -1665,6 +1681,13 @@ EXPORT_SYMBOL(nvhost_client_device_init);
1665 1681
1666int nvhost_client_device_release(struct platform_device *dev) 1682int nvhost_client_device_release(struct platform_device *dev)
1667{ 1683{
1684#ifdef CONFIG_EVENTLIB
1685 struct nvhost_device_data *pdata = platform_get_drvdata(dev);
1686
1687 if (pdata->eventlib_id)
1688 keventlib_unregister(pdata->eventlib_id);
1689#endif
1690
1668 /* Release nvhost module resources */ 1691 /* Release nvhost module resources */
1669 nvhost_module_deinit(dev); 1692 nvhost_module_deinit(dev);
1670 1693
@@ -1785,3 +1808,53 @@ struct nvhost_channel *nvhost_find_chan_by_clientid(
1785 1808
1786 return ch; 1809 return ch;
1787} 1810}
1811
1812#ifdef CONFIG_EVENTLIB
1813void nvhost_eventlib_log_task(struct platform_device *pdev,
1814 u32 syncpt_id,
1815 u32 syncpt_thresh,
1816 u64 timestamp_start,
1817 u64 timestamp_end)
1818{
1819 struct nvhost_device_data *pdata = platform_get_drvdata(pdev);
1820 union nvhost_event_union event;
1821
1822 if (!pdata->eventlib_id)
1823 return;
1824
1825 /*
1826 * Write task start event
1827 */
1828 event.task_start.syncpt_id = syncpt_id;
1829 event.task_start.syncpt_thresh = syncpt_thresh;
1830 event.task_start.class_id = pdata->class;
1831
1832 keventlib_write(pdata->eventlib_id,
1833 &event,
1834 sizeof(event),
1835 NVHOST_TASK_START,
1836 timestamp_start);
1837
1838 /*
1839 * Write task end event
1840 */
1841 event.task_end.syncpt_id = syncpt_id;
1842 event.task_end.syncpt_thresh = syncpt_thresh;
1843 event.task_end.class_id = pdata->class;
1844
1845 keventlib_write(pdata->eventlib_id,
1846 &event,
1847 sizeof(event),
1848 NVHOST_TASK_END,
1849 timestamp_end);
1850}
1851#else
1852void nvhost_eventlib_log_task(struct platform_device *pdev,
1853 u32 syncpt_id,
1854 u32 syncpt_thres,
1855 u64 timestamp_start,
1856 u64 timestamp_end)
1857{
1858}
1859#endif
1860EXPORT_SYMBOL(nvhost_eventlib_log_task);
diff --git a/include/linux/nvhost.h b/include/linux/nvhost.h
index 96ac4b170..a8185c7d8 100644
--- a/include/linux/nvhost.h
+++ b/include/linux/nvhost.h
@@ -375,6 +375,9 @@ struct nvhost_device_data {
375 375
376 /* number of frames mlock can be locked for */ 376 /* number of frames mlock can be locked for */
377 u32 mlock_timeout_factor; 377 u32 mlock_timeout_factor;
378
379 /* eventlib id for the device */
380 int eventlib_id;
378}; 381};
379 382
380 383
@@ -634,6 +637,13 @@ static inline void nvhost_unregister_dump_device(struct platform_device *dev)
634{ 637{
635} 638}
636 639
640static inline void nvhost_eventlib_log_task(struct platform_device *pdev,
641 u32 syncpt_id,
642 u32 syncpt_thres,
643 u64 timestamp_start,
644 u64 timestamp_end)
645{
646}
637#else 647#else
638 648
639#ifdef CONFIG_DEBUG_FS 649#ifdef CONFIG_DEBUG_FS
@@ -736,6 +746,12 @@ u32 nvhost_syncpt_read_maxval(struct platform_device *dev, u32 id);
736void nvhost_syncpt_set_minval(struct platform_device *dev, u32 id, u32 val); 746void nvhost_syncpt_set_minval(struct platform_device *dev, u32 id, u32 val);
737void nvhost_syncpt_set_maxval(struct platform_device *dev, u32 id, u32 val); 747void nvhost_syncpt_set_maxval(struct platform_device *dev, u32 id, u32 val);
738 748
749void nvhost_eventlib_log_task(struct platform_device *pdev,
750 u32 syncpt_id,
751 u32 syncpt_thres,
752 u64 timestamp_start,
753 u64 timestamp_end);
754
739/* public host1x interrupt management APIs */ 755/* public host1x interrupt management APIs */
740int nvhost_intr_register_notifier(struct platform_device *pdev, 756int nvhost_intr_register_notifier(struct platform_device *pdev,
741 u32 id, u32 thresh, 757 u32 id, u32 thresh,
diff --git a/include/uapi/linux/nvhost_events.h b/include/uapi/linux/nvhost_events.h
new file mode 100644
index 000000000..1935f6edd
--- /dev/null
+++ b/include/uapi/linux/nvhost_events.h
@@ -0,0 +1,71 @@
1/*
2 * Eventlib interface for PVA
3 *
4 * Copyright (c) 2016-2017, NVIDIA Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef NVHOST_EVENTS_H
20#define NVHOST_EVENTS_H
21
22enum {
23 NVHOST_SCHEMA_VERSION = 1
24};
25
26#define NVHOST_EVENT_PROVIDER_NAME "nvhost"
27
28/* Marks that the task is moving to execution */
29struct nvhost_task_start {
30 /* Engine class ID */
31 u32 class_id;
32
33 /* Syncpoint ID */
34 u32 syncpt_id;
35
36 /* Threshold for task completion */
37 u32 syncpt_thresh;
38} __packed;
39
40/* Marks that the task is completed */
41struct nvhost_task_end {
42 /* Engine class ID */
43 u32 class_id;
44
45 /* Syncpoint ID */
46 u32 syncpt_id;
47
48 /* Threshold for task completion */
49 u32 syncpt_thresh;
50} __packed;
51
52enum {
53 /* struct nvhost_task_start */
54 NVHOST_TASK_START = 0,
55
56 /* struct nvhost_task_end */
57 NVHOST_TASK_END = 1,
58
59 NVHOST_NUM_EVENT_TYPES = 2
60};
61
62union nvhost_event_union {
63 struct nvhost_task_start task_start;
64 struct nvhost_task_end task_end;
65};
66
67enum {
68 NVHOST_NUM_CUSTOM_FILTER_FLAGS = 0
69};
70
71#endif /* NVHOST_EVENTS_H */