All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC v2 00/11] Intro to Hardware timestamping engine
@ 2021-09-30 23:26 Dipen Patel
  2021-09-30 23:26 ` [RFC v2 01/11] Documentation: Add HTE subsystem guide Dipen Patel
                   ` (10 more replies)
  0 siblings, 11 replies; 33+ messages in thread
From: Dipen Patel @ 2021-09-30 23:26 UTC (permalink / raw)
  To: thierry.reding, jonathanh, linux-kernel, linux-tegra, linux-gpio,
	linus.walleij, bgolaszewski, warthog618, devicetree, linux-doc,
	robh+dt
  Cc: Dipen Patel

This patch series introduces new subsystem called hardware timestamping
engine (HTE). It offers functionality such as timestamping through hardware
means in realtime. The HTE subsystem centralizes HTE provider and consumers
where providers can register themselves and the consumers can request
interested entity which could be lines, GPIO, signals or buses. The
HTE subsystem provides timestamp in nano seconds, having said that the provider
need to convert the timestamp if its not in that unit. There was upstream
discussion about the HTE at
https://lore.kernel.org/lkml/4c46726d-fa35-1a95-4295-bca37c8b6fe3@nvidia.com/

To summarize upstream discussion:
- It was heavily favoured by Linus and Kent to extend GPIOLIB and supporting
GPIO drivers to add HTE functionality and I agreed to experiment with it.
This patch series implements and extends GPIOLIB, GPIOLIB-CDEV and GPIO tegra
driver.
- Discussed possibility to add HTE provider as irqchip instead which
was argued against as HTE devices are not necessarily event emitting
devices. This RFC version 2 however tries to emulate threaded irq style
implementation.
- Discussed other possibility if HTE device can be added as posix clock
type like PTP clocks. That was also argues against since HTE devices
are not necessarily tightly coupled with hardware clock.

Typical HTE provider does following:
- Register itself with HTE subsystem
- Provide request, release, enable, disable timestamp and
get_clk_src_info callbacks to HTE subsystem.
- Provide optional xlate callback to the subsystem which can translate
consumer provided logical ids into actual ids of the entity, where entity here
is the provider dependent and could be GPIO, in chip lines or signals, buses
etc...This converted id will be used between HTE subsystem and the provider for
below bullet point.
- Push timestamps to the subsystem. This happens when HTE provider has
timestamp data available and willing to push it to HTE subsystem.
- Unregister itself on exit.

Typical HTE consumer does following:
- Request interested entity it wishes to timestamp in realtime to the
subsystem.
- The subsystem does necessary communications with the provider to
complete the request, which includes translating logical id of the entity to
provider dependent physical/actual id and enabling hardware timestamping on
requested id.
- The request includes callbacks, it will be used to push timestamps.
Optionally, the consumer can provided threaded callback, if specified, the HTE
subsystem will create kernel thread responsible executing the threaded callback.
- Release entity and its resources.

HTE and GPIOLIB:
- For the HTE provider which can timestamp GPIO lines.
- For the GPIO consumers, either in kernel or userspace, The GPIOLIB and its
CDEV framework are extended as frontend to the HTE by introducing new APIs.
- Tegra194 AON GPIO controller has HTE support known as GTE
(Generic Timestamping Engine). The tegra gpio driver is modified to accommodate
HTE functionality.

Changes in V2:
- Removed buffer management and related APIs from the HTE core.
- Removed timestamp retrieve APIs from the HTE core.
- Modified request API with two callbacks, second callback is invoked in thread
context and is optional, while first callback is mandatory and used to push
timestamp data to consumers.
- Replaced hte with hardware-timestamping in DT bindings as hte appeared too
short according to review comments.

Dipen Patel (11):
  Documentation: Add HTE subsystem guide
  drivers: Add hardware timestamp engine (HTE)
  hte: Add tegra194 HTE kernel provider
  dt-bindings: Add HTE bindings
  hte: Add Tegra194 IRQ HTE test driver
  gpiolib: Add HTE support
  gpio: tegra186: Add HTE in gpio-tegra186 driver
  gpiolib: cdev: Add hardware timestamp clock type
  tools: gpio: Add new hardware clock type
  hte: Add tegra GPIO HTE test driver
  MAINTAINERS: Added HTE Subsystem

 .../bindings/gpio/nvidia,tegra186-gpio.txt    |   7 +
 .../hte/hardware-timestamps-common.yaml       |  29 +
 .../devicetree/bindings/hte/hte-consumer.yaml |  48 +
 .../bindings/hte/nvidia,tegra194-hte.yaml     |  79 ++
 Documentation/hte/hte.rst                     |  83 ++
 Documentation/hte/index.rst                   |  22 +
 Documentation/hte/tegra194-hte.rst            |  56 ++
 Documentation/index.rst                       |   1 +
 MAINTAINERS                                   |   8 +
 drivers/Kconfig                               |   2 +
 drivers/Makefile                              |   1 +
 drivers/gpio/gpio-tegra186.c                  |  89 ++
 drivers/gpio/gpiolib-cdev.c                   | 161 +++-
 drivers/gpio/gpiolib.c                        |  73 ++
 drivers/gpio/gpiolib.h                        |  12 +
 drivers/hte/Kconfig                           |  50 +
 drivers/hte/Makefile                          |   5 +
 drivers/hte/hte-tegra194-gpio-test.c          | 252 +++++
 drivers/hte/hte-tegra194-irq-test.c           | 169 ++++
 drivers/hte/hte-tegra194.c                    | 554 +++++++++++
 drivers/hte/hte.c                             | 907 ++++++++++++++++++
 include/linux/gpio/consumer.h                 |  19 +-
 include/linux/gpio/driver.h                   |  14 +
 include/linux/hte.h                           | 248 +++++
 include/uapi/linux/gpio.h                     |   1 +
 tools/gpio/gpio-event-mon.c                   |   6 +-
 26 files changed, 2884 insertions(+), 12 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/hte/hardware-timestamps-common.yaml
 create mode 100644 Documentation/devicetree/bindings/hte/hte-consumer.yaml
 create mode 100644 Documentation/devicetree/bindings/hte/nvidia,tegra194-hte.yaml
 create mode 100644 Documentation/hte/hte.rst
 create mode 100644 Documentation/hte/index.rst
 create mode 100644 Documentation/hte/tegra194-hte.rst
 create mode 100644 drivers/hte/Kconfig
 create mode 100644 drivers/hte/Makefile
 create mode 100644 drivers/hte/hte-tegra194-gpio-test.c
 create mode 100644 drivers/hte/hte-tegra194-irq-test.c
 create mode 100644 drivers/hte/hte-tegra194.c
 create mode 100644 drivers/hte/hte.c
 create mode 100644 include/linux/hte.h


base-commit: 2d02a18f75fc81177a4e30f3aaaed9af06cc3adc
-- 
2.17.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [RFC v2 01/11] Documentation: Add HTE subsystem guide
  2021-09-30 23:26 [RFC v2 00/11] Intro to Hardware timestamping engine Dipen Patel
@ 2021-09-30 23:26 ` Dipen Patel
  2021-10-02  0:18   ` Randy Dunlap
  2021-09-30 23:26 ` [RFC v2 02/11] drivers: Add hardware timestamp engine (HTE) Dipen Patel
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 33+ messages in thread
From: Dipen Patel @ 2021-09-30 23:26 UTC (permalink / raw)
  To: thierry.reding, jonathanh, linux-kernel, linux-tegra, linux-gpio,
	linus.walleij, bgolaszewski, warthog618, devicetree, linux-doc,
	robh+dt
  Cc: Dipen Patel

Adding hte document which can help understand various APIs implemented
in HTE framework for the HTE producers and the consumers.

Signed-off-by: Dipen Patel <dipenp@nvidia.com>
---
Changes in v2:
- Removed explanation, instead added kernel-doc references.

 Documentation/hte/hte.rst | 83 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 83 insertions(+)
 create mode 100644 Documentation/hte/hte.rst

diff --git a/Documentation/hte/hte.rst b/Documentation/hte/hte.rst
new file mode 100644
index 000000000000..c9b1badae601
--- /dev/null
+++ b/Documentation/hte/hte.rst
@@ -0,0 +1,83 @@
+============================================
+The Linux Hardware Timestamping Engine (HTE)
+============================================
+
+:Author: Dipen Patel
+
+Introduction
+------------
+
+Certain devices have built in hardware timestamping engines which can
+monitor sets of system signals, lines, buses etc... in realtime for state
+change; upon detecting the change they can automatically store the timestamp at
+the moment of occurrence. Such functionality may help achieve better accuracy
+in obtaining timestamp than using software counterparts i.e. ktime and friends.
+
+This document describes the API that can be used by hardware timestamping
+engine provider and consumer drivers that want to use the hardware timestamping
+engine (HTE) framework. Both consumers and providers must
+#include <linux/hte.h>.
+
+The HTE framework APIs for the providers
+----------------------------------------
+
+.. kernel-doc:: drivers/hte/hte.c
+   :functions: devm_hte_register_chip hte_push_ts_ns
+
+The HTE framework APIs for the consumers
+----------------------------------------
+
+.. kernel-doc:: drivers/hte/hte.c
+   :functions: devm_of_hte_request_ts hte_req_ts_by_hte_name hte_release_ts hte_enable_ts hte_disable_ts hte_get_clk_src_info
+
+The HTE framework public structures
+-----------------------------------
+.. kernel-doc:: include/linux/hte.h
+
+
+More on the HTE timestamp data
+------------------------------
+The struct hte_ts_data is used to pass timestamp details between the consumers
+and the providers. It expresses timestamp data in nano second in u64 data
+type. For now all the HTE APIs using struct hte_ts_data requires tsc to be in
+nano seconds. An example of the typical hte_ts_data data life cycle, for the
+GPIO line is as follows::
+
+ - Monitors GPIO line change.
+ - Detects the state change on GPIO line.
+ - Converts timestamps in nano seconds and stores it in tsc.
+ - Stores GPIO direction in dir variable if the provider has that hardware
+ capability.
+ - Pushes this hte_ts_data object to HTE subsystem.
+ - HTE subsystem increments seq counter and invokes consumer provided callback.
+ Based on callback return value, the HTE starts kernel thread and invokes
+ secondary callback in the thread context.
+
+HTE subsystem debugfs attributes
+--------------------------------
+HTE subsystem creates debugfs attributes at ``/sys/kernel/debug/hte/``.
+It also creates line/signal related debugfs attributes at
+``/sys/kernel/debug/hte/<provider>/<label or line id>/``.
+
+`ts_requested`
+		The total number of entities requested from the given provider,
+		where entity is the provider specific and could represent
+		lines, GPIO, chip signals, buses etc...
+                The attribute will be availble at
+		``/sys/kernel/debug/hte/<provider>/``.
+
+		Read only value
+
+`total_ts`
+		The total number of entities supported by the provider.
+                The attribute will be availble at
+		``/sys/kernel/debug/hte/<provider>/``.
+
+		Read only value
+
+`dropped_timestamps`
+		The dropped timestamps for a given line.
+                The attribute will be availble at
+		``/sys/kernel/debug/hte/<provider>/<label or line id>/``.
+
+		Read only value
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [RFC v2 02/11] drivers: Add hardware timestamp engine (HTE)
  2021-09-30 23:26 [RFC v2 00/11] Intro to Hardware timestamping engine Dipen Patel
  2021-09-30 23:26 ` [RFC v2 01/11] Documentation: Add HTE subsystem guide Dipen Patel
@ 2021-09-30 23:26 ` Dipen Patel
  2021-10-01 23:53   ` Randy Dunlap
  2021-09-30 23:26 ` [RFC v2 03/11] hte: Add tegra194 HTE kernel provider Dipen Patel
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 33+ messages in thread
From: Dipen Patel @ 2021-09-30 23:26 UTC (permalink / raw)
  To: thierry.reding, jonathanh, linux-kernel, linux-tegra, linux-gpio,
	linus.walleij, bgolaszewski, warthog618, devicetree, linux-doc,
	robh+dt
  Cc: Dipen Patel

Some devices can timestamp system lines/signals/Buses in real-time
using the hardware counter or other hardware means which can give
finer granularity and help avoid jitter introduced by software
timestamping. To utilize such functionality, this patchset creates
HTE subsystem where devices can register themselves as providers so
that the consumers devices can request specific line from the
providers.

It provides below APIs for the provider:
- devm_hte_register_chip -- To register the HTE provider.
- hte_push_ts_ns() -- To push timestamp data into HTE subsystem.

It provides below APIs for the consumer:
- devm_of_hte_request_ts() -- Request timestamp functionality.
- hte_req_ts_by_hte_name() -- To request timestamp functionality by
using HTE provider dt node.
- hte_enable_ts() -- To disable timestamp functionality.
- hte_disable_ts() -- To enable timestamp functionality.
- hte_release_ts() -- To release timestamp functionality and its
associated resources.
- hte_get_clk_src_info() -- To query clock source information from
the provider

The detail about parameters and API usage are described in each
functions definitions in drivers/hte/hte.c file.

The patch adds compilation support in Makefile and menu options in
Kconfig.

Signed-off-by: Dipen Patel <dipenp@nvidia.com>
Reported-by: kernel test robot <lkp@intel.com>
---
Changes in v2:
- Removed buffer abstraction layer as well related APIs, HTE now will not store
any data, instead will pass to consumer as soon as it is available.
- Removed unnecessary dynamical allocations
- Removed timestamp retrieve API
- Removed release, unregister related APIs as their counterpart are resource
managed.
- Added kernel thread implementation if consumer indicates threaded callback
during request API time.
- Changed hte_req_ts_by_dt_node API to remove device node exposure from the
interface, instead consumer will their device node with property name that
indicates the provider it wants to use.

 drivers/Kconfig      |   2 +
 drivers/Makefile     |   1 +
 drivers/hte/Kconfig  |  22 ++
 drivers/hte/Makefile |   2 +
 drivers/hte/hte.c    | 907 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/hte.h  | 248 ++++++++++++
 6 files changed, 1182 insertions(+)
 create mode 100644 drivers/hte/Kconfig
 create mode 100644 drivers/hte/Makefile
 create mode 100644 drivers/hte/hte.c
 create mode 100644 include/linux/hte.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index 30d2db37cc87..2940a23c6cf2 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -234,4 +234,6 @@ source "drivers/interconnect/Kconfig"
 source "drivers/counter/Kconfig"
 
 source "drivers/most/Kconfig"
+
+source "drivers/hte/Kconfig"
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index be5d40ae1488..087c08e846e6 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -188,3 +188,4 @@ obj-$(CONFIG_GNSS)		+= gnss/
 obj-$(CONFIG_INTERCONNECT)	+= interconnect/
 obj-$(CONFIG_COUNTER)		+= counter/
 obj-$(CONFIG_MOST)		+= most/
+obj-$(CONFIG_HTE)		+= hte/
diff --git a/drivers/hte/Kconfig b/drivers/hte/Kconfig
new file mode 100644
index 000000000000..6fdf243d281b
--- /dev/null
+++ b/drivers/hte/Kconfig
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: GPL-2.0-only
+menuconfig HTE
+	bool "Hardware Timestamping Engine (HTE) Support"
+	help
+	  Hardware Timestamping Engine (HTE) Support.
+
+	  Some devices provide hardware timestamping engine which can timestamp
+	  certain device lines/signals in realtime. This way to provide
+	  hardware assisted timestamp to generic signals like GPIOs, IRQs lines
+	  comes with benefit for the applications like autonomous machines
+	  needing accurate timestamping event with less jitter.
+
+	  This framework provides a generic interface to such HTE devices
+	  within the Linux kernel. It provides an API to register and
+	  unregister a HTE provider chip, configurable sw buffer to
+	  store the timestamps, push the timestamp from the HTE providers and
+	  retrieve timestamps for the consumers. It also provides means for the
+	  consumers to request signals it wishes to hardware timestamp and
+	  release them if not required.
+
+	  If unsure, say no.
+
diff --git a/drivers/hte/Makefile b/drivers/hte/Makefile
new file mode 100644
index 000000000000..fc03bdf44427
--- /dev/null
+++ b/drivers/hte/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_HTE)		+= hte.o
+
diff --git a/drivers/hte/hte.c b/drivers/hte/hte.c
new file mode 100644
index 000000000000..6ba2e4698a6e
--- /dev/null
+++ b/drivers/hte/hte.c
@@ -0,0 +1,907 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 NVIDIA Corporation
+ *
+ * Author: Dipen Patel <dipenp@nvidia.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/uaccess.h>
+#include <linux/hte.h>
+#include <linux/delay.h>
+#include <linux/debugfs.h>
+#include <linux/kthread.h>
+
+#define HTE_TS_NAME_LEN		10
+
+/* Global list of the HTE devices */
+static DEFINE_SPINLOCK(hte_lock);
+static LIST_HEAD(hte_devices);
+
+enum {
+	HTE_TS_REGISTERED,
+	HTE_TS_DISABLE,
+};
+
+enum {
+	HTE_CB_RUN_THREAD,
+	HTE_CB_NUM,
+};
+
+/**
+ * struct hte_ts_info - Information related to requested timestamp.
+ *
+ * @xlated_id: Timestamp ID as understood between HTE subsys and HTE provider,
+ * See xlate callback API.
+ * @flags: Flags holding state informations.
+ * @hte_cb_flags: Callback related flags.
+ * @seq: Timestamp sequence counter.
+ * @hte_name: Indicates if HTE core has set name for this timestamp entity.
+ * @cb: Callback function provided by clients.
+ * @tcb: Threaded callback function provided by clients.
+ * @dropped_ts: Dropped timestamps.
+ * @slock: Spin lock.
+ * @thread: Thread task when tcb is provided.
+ * @req_mlock: Lock during timestamp request/release APIs.
+ * @ts_dbg_root: Root for the debug fs.
+ * @gdev: HTE abstract device that this timestamp belongs to.
+ * @cl_data: Client specific data.
+ */
+struct hte_ts_info {
+	u32 xlated_id;
+	unsigned long flags;
+	unsigned long hte_cb_flags;
+	u64 seq;
+	bool hte_name;
+	hte_ts_cb_t cb;
+	hte_ts_threaded_cb_t tcb;
+	atomic_t dropped_ts;
+	spinlock_t slock;
+	struct task_struct *thread;
+	struct mutex req_mlock;
+	struct dentry *ts_dbg_root;
+	struct hte_device *gdev;
+	void *cl_data;
+};
+
+/**
+ * struct hte_device - HTE abstract device
+ * @nlines: Number of entities this device supports.
+ * @ts_req: Total number of entities requested.
+ * @sdev: Device used at various debug prints.
+ * @dbg_root: Root directory for debug fs.
+ * @list: List node to store hte_device for each provider.
+ * @chip: HTE chip providing this HTE device.
+ * @owner: helps prevent removal of modules when in use.
+ * @ei: Timestamp information.
+ */
+struct hte_device {
+	u32 nlines;
+	atomic_t ts_req;
+	struct device *sdev;
+	struct dentry *dbg_root;
+	struct list_head list;
+	struct hte_chip *chip;
+	struct module *owner;
+	struct hte_ts_info ei[];
+};
+
+#ifdef CONFIG_DEBUG_FS
+
+static struct dentry *hte_root;
+
+static int __init hte_subsys_dbgfs_init(void)
+{
+	/* creates /sys/kernel/debug/hte/ */
+	hte_root = debugfs_create_dir("hte", NULL);
+
+	return 0;
+}
+subsys_initcall(hte_subsys_dbgfs_init);
+
+static void hte_chip_dbgfs_init(struct hte_device *gdev)
+{
+	const struct hte_chip *chip = gdev->chip;
+	const char *name = chip->name ? chip->name : dev_name(chip->dev);
+
+	gdev->dbg_root = debugfs_create_dir(name, hte_root);
+
+	debugfs_create_atomic_t("ts_requested", 0444, gdev->dbg_root,
+				&gdev->ts_req);
+	debugfs_create_u32("total_ts", 0444, gdev->dbg_root,
+			   &gdev->nlines);
+}
+
+static void hte_ts_dbgfs_init(const char *name, struct hte_ts_info *ei)
+{
+	if (!ei->gdev->dbg_root || !name)
+		return;
+
+	ei->ts_dbg_root = debugfs_create_dir(name, ei->gdev->dbg_root);
+
+	debugfs_create_atomic_t("dropped_timestamps", 0444, ei->ts_dbg_root,
+				&ei->dropped_ts);
+}
+
+#else
+
+static void hte_chip_dbgfs_init(struct hte_device *gdev)
+{
+}
+
+static void hte_ts_dbgfs_init(const char *name, struct hte_ts_info *ei)
+{
+}
+
+#endif
+
+/**
+ * hte_release_ts() - Consumer calls this API to release the entity, where
+ * entity could be anything providers support, like lines, signals, buses,
+ * etc...
+ *
+ * @desc: timestamp descriptor, this is the same as returned by the request API.
+ *
+ * Context: debugfs_remove_recursive() function call may use sleeping locks,
+ *	    not suitable from atomic context.
+ * Returns: 0 on success or a negative error code on failure.
+ */
+int hte_release_ts(struct hte_ts_desc *desc)
+{
+	u32 id;
+	int ret = 0;
+	unsigned long flag;
+	struct hte_device *gdev;
+	struct hte_ts_info *ei;
+
+	if (!desc)
+		return -EINVAL;
+
+	ei = desc->hte_data;
+
+	if (!ei || !ei->gdev)
+		return -EINVAL;
+
+	gdev = ei->gdev;
+	id = desc->con_id;
+
+	mutex_lock(&ei->req_mlock);
+
+	if (!test_bit(HTE_TS_REGISTERED, &ei->flags)) {
+		dev_info(gdev->sdev, "id:%d is not registered", id);
+		ret = -EUSERS;
+		goto unlock;
+	}
+
+	ret = gdev->chip->ops->release(gdev->chip, ei->xlated_id);
+	if (ret) {
+		dev_err(gdev->sdev, "id: %d free failed\n", id);
+		goto unlock;
+	}
+
+	if (ei->hte_name)
+		kfree(desc->name);
+
+	debugfs_remove_recursive(ei->ts_dbg_root);
+
+	spin_lock_irqsave(&ei->slock, flag);
+
+	atomic_dec(&gdev->ts_req);
+	atomic_set(&ei->dropped_ts, 0);
+
+	ei->seq = 0;
+	desc->hte_data = NULL;
+
+	clear_bit(HTE_TS_REGISTERED, &ei->flags);
+
+	spin_unlock_irqrestore(&ei->slock, flag);
+
+	if (ei->tcb) {
+		kthread_stop(ei->thread);
+		put_task_struct(ei->thread);
+	}
+
+	ei->cb = NULL;
+	ei->tcb = NULL;
+	ei->thread = NULL;
+	ei->cl_data = NULL;
+
+	module_put(gdev->owner);
+unlock:
+	mutex_unlock(&ei->req_mlock);
+	dev_dbg(gdev->sdev, "release id: %d\n", id);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(hte_release_ts);
+
+static int hte_ts_dis_en_common(struct hte_ts_desc *desc, bool en)
+{
+	u32 ts_id;
+	struct hte_device *gdev;
+	struct hte_ts_info *ei;
+	int ret;
+	unsigned long flag;
+
+	if (!desc)
+		return -EINVAL;
+
+	ei = desc->hte_data;
+
+	if (!ei || !ei->gdev)
+		return -EINVAL;
+
+	gdev = ei->gdev;
+	ts_id = desc->con_id;
+
+	mutex_lock(&ei->req_mlock);
+
+	if (!test_bit(HTE_TS_REGISTERED, &ei->flags)) {
+		dev_dbg(gdev->sdev, "id:%d is not registered", ts_id);
+		ret = -EUSERS;
+		goto out;
+	}
+
+	spin_lock_irqsave(&ei->slock, flag);
+
+	if (en) {
+		if (!test_bit(HTE_TS_DISABLE, &ei->flags)) {
+			ret = 0;
+			goto out_unlock;
+		}
+
+		spin_unlock_irqrestore(&ei->slock, flag);
+		ret = gdev->chip->ops->enable(gdev->chip, ei->xlated_id);
+		if (ret) {
+			dev_warn(gdev->sdev, "id: %d enable failed\n",
+				 ts_id);
+			goto out;
+		}
+
+		spin_lock_irqsave(&ei->slock, flag);
+		clear_bit(HTE_TS_DISABLE, &ei->flags);
+	} else {
+		if (test_bit(HTE_TS_DISABLE, &ei->flags)) {
+			ret = 0;
+			goto out_unlock;
+		}
+
+		spin_unlock_irqrestore(&ei->slock, flag);
+		ret = gdev->chip->ops->disable(gdev->chip, ei->xlated_id);
+		if (ret) {
+			dev_warn(gdev->sdev, "id: %d disable failed\n",
+				 ts_id);
+			goto out;
+		}
+
+		spin_lock_irqsave(&ei->slock, flag);
+		set_bit(HTE_TS_DISABLE, &ei->flags);
+	}
+
+out_unlock:
+	spin_unlock_irqrestore(&ei->slock, flag);
+out:
+	mutex_unlock(&ei->req_mlock);
+	return ret;
+}
+
+/**
+ * hte_disable_ts() - Disable timestamp on given descriptor.
+ *
+ * The API does not release any resources associated with desc.
+ *
+ * @desc: ts descriptor, this is the same as returned by the request API.
+ *
+ * Context: Holds mutex lock, not suitable from atomic context.
+ * Returns: 0 on success or a negative error code on failure.
+ */
+int hte_disable_ts(struct hte_ts_desc *desc)
+{
+	return hte_ts_dis_en_common(desc, false);
+}
+EXPORT_SYMBOL_GPL(hte_disable_ts);
+
+/**
+ * hte_enable_ts() - Enable timestamp on given descriptor.
+ *
+ * @desc: ts descriptor, this is the same as returned by the request API.
+ *
+ * Context: Holds mutex lock, not suitable from atomic context.
+ * Returns: 0 on success or a negative error code on failure.
+ */
+int hte_enable_ts(struct hte_ts_desc *desc)
+{
+	return hte_ts_dis_en_common(desc, true);
+}
+EXPORT_SYMBOL_GPL(hte_enable_ts);
+
+static int hte_simple_xlate(struct hte_chip *gc,
+			    const struct of_phandle_args *args,
+			    struct hte_ts_desc *desc,
+			    u32 *id)
+{
+	if (!id || !desc || !gc)
+		return -EINVAL;
+
+	/*
+	 * For the providers which do not have any internal mappings between
+	 * logically exposed ids and actual ids, will set both
+	 * the same.
+	 *
+	 * In case there is a internal mapping needed, providers will need to
+	 * provide its own xlate function where con_id will be sent as
+	 * args[0] and it will return xlated id. Later xlated id will be
+	 * used for any future exchanges between provider and subsystems.
+	 */
+
+	if (args) {
+		if (gc->of_hte_n_cells < 1)
+			return -EINVAL;
+
+		if (args->args_count != gc->of_hte_n_cells)
+			return -EINVAL;
+
+		*id = args->args[0];
+		desc->con_id = *id;
+	} else {
+		*id = desc->con_id;
+	}
+
+	if (desc->con_id > gc->nlines)
+		return -EINVAL;
+
+	desc->hte_data = NULL;
+
+	return 0;
+}
+
+static int _hte_wait_for_ts_data(struct hte_ts_info *ei)
+{
+	for (;;) {
+		set_current_state(TASK_INTERRUPTIBLE);
+
+		if (kthread_should_stop()) {
+			if (test_and_clear_bit(HTE_CB_RUN_THREAD,
+			    &ei->hte_cb_flags)) {
+				__set_current_state(TASK_RUNNING);
+				return 0;
+			}
+			__set_current_state(TASK_RUNNING);
+			return -1;
+		}
+
+		if (test_and_clear_bit(HTE_CB_RUN_THREAD,
+				       &ei->hte_cb_flags)) {
+			__set_current_state(TASK_RUNNING);
+			return 0;
+		}
+		schedule();
+	}
+}
+
+static int _hte_threadfn(void *data)
+{
+	struct hte_ts_info *ei = data;
+
+	while (!_hte_wait_for_ts_data(ei))
+		ei->tcb(ei->cl_data);
+
+	return 0;
+}
+
+static int _hte_setup_thread(struct hte_ts_info *ei, u32 id)
+{
+	struct task_struct *t;
+
+	t = kthread_create(_hte_threadfn, ei, "hte-%u", id);
+	if (IS_ERR(t))
+		return PTR_ERR(t);
+
+	ei->thread = get_task_struct(t);
+
+	return 0;
+}
+
+static int ___hte_req_ts(struct hte_device *gdev, struct hte_ts_desc *desc,
+			 u32 xlated_id, hte_ts_cb_t cb,
+			 hte_ts_threaded_cb_t tcb, void *data)
+{
+	struct hte_ts_info *ei;
+	int ret;
+	u32 con_id = desc->con_id;
+
+	if (!try_module_get(gdev->owner))
+		return -ENODEV;
+
+	ei = &gdev->ei[xlated_id];
+	ei->xlated_id = xlated_id;
+
+	/*
+	 * There is a chance that multiple consumers requesting same entity,
+	 * lock here.
+	 */
+	mutex_lock(&ei->req_mlock);
+
+	if (test_bit(HTE_TS_REGISTERED, &ei->flags)) {
+		dev_dbg(gdev->chip->dev, "id:%u is already registered",
+			xlated_id);
+		ret = -EUSERS;
+		goto unlock;
+	}
+
+	ei->cb = cb;
+	ei->tcb = tcb;
+	if (tcb) {
+		ret = _hte_setup_thread(ei, xlated_id);
+		if (ret < 0) {
+			dev_err(gdev->chip->dev, "setting thread failed\n");
+			goto unlock;
+		}
+	}
+
+	ret = gdev->chip->ops->request(gdev->chip, xlated_id);
+	if (ret < 0) {
+		dev_err(gdev->chip->dev, "ts request failed\n");
+		goto unlock;
+	}
+
+	desc->hte_data = ei;
+	ei->cl_data = data;
+
+	atomic_inc(&gdev->ts_req);
+
+	ei->hte_name = false;
+	if (!desc->name) {
+		desc->name = kzalloc(HTE_TS_NAME_LEN, GFP_KERNEL);
+		if (desc->name) {
+			scnprintf(desc->name, HTE_TS_NAME_LEN, "ts_%u",
+				  con_id);
+			ei->hte_name = true;
+		}
+	}
+
+	hte_ts_dbgfs_init(desc->name, ei);
+	set_bit(HTE_TS_REGISTERED, &ei->flags);
+
+	mutex_unlock(&ei->req_mlock);
+
+	dev_dbg(gdev->chip->dev, "id: %u, xlated id:%u", con_id, xlated_id);
+
+	return 0;
+
+unlock:
+	module_put(gdev->owner);
+	mutex_unlock(&ei->req_mlock);
+
+	return ret;
+}
+
+static struct hte_device *of_node_to_htedevice(struct device_node *np)
+{
+	struct hte_device *gdev;
+
+	spin_lock(&hte_lock);
+
+	list_for_each_entry(gdev, &hte_devices, list)
+		if (gdev->chip && gdev->chip->dev &&
+		    gdev->chip->dev->of_node == np) {
+			spin_unlock(&hte_lock);
+			return gdev;
+		}
+
+	spin_unlock(&hte_lock);
+
+	return ERR_PTR(-ENODEV);
+}
+
+static struct hte_device *of_hte_dev_get(struct device *dev,
+					 struct device_node *np,
+					 const char *label,
+					 struct of_phandle_args *args)
+{
+	struct hte_device *gdev = NULL;
+	int index = 0;
+	int err;
+
+	if (label) {
+		index = of_property_match_string(np,
+						 "hardware-timestamps-names",
+						 label);
+		if (index < 0)
+			return ERR_PTR(index);
+	}
+
+	err = of_parse_phandle_with_args(np, "hardware-timestamps",
+					 "#hardware-timestamps-cells", index,
+					 args);
+	if (err) {
+		pr_err("%s(): can't parse \"hardware-timestamps\" property\n",
+		       __func__);
+		return ERR_PTR(err);
+	}
+
+	gdev = of_node_to_htedevice(args->np);
+	if (IS_ERR(gdev)) {
+		pr_err("%s(): HTE chip not found\n", __func__);
+		of_node_put(args->np);
+		return gdev;
+	}
+
+	return gdev;
+}
+
+static int __hte_req_ts(struct device *dev, struct hte_ts_desc *desc,
+			hte_ts_cb_t cb, hte_ts_threaded_cb_t tcb, void *data)
+{
+	struct hte_device *gdev = NULL;
+	struct of_phandle_args args;
+	int ret;
+	u32 xlated_id;
+
+	gdev = of_hte_dev_get(dev, dev->of_node, desc->name, &args);
+	if (IS_ERR(gdev))
+		return PTR_ERR(gdev);
+
+	if (!gdev->chip) {
+		pr_debug("requested id does not have provider\n");
+		return -ENODEV;
+	}
+
+	ret = gdev->chip->xlate(gdev->chip, &args, desc, &xlated_id);
+	if (ret < 0)
+		goto put;
+
+	ret = ___hte_req_ts(gdev, desc, xlated_id, cb, tcb, data);
+	if (ret < 0)
+		goto put;
+
+	return 0;
+
+put:
+	of_node_put(args.np);
+
+	return ret;
+}
+
+static void __devm_hte_release_ts(void *res)
+{
+	hte_release_ts(res);
+}
+
+/**
+ * devm_of_hte_request_ts() - Resource managed API to request the HTE facility
+ * on the specified entity, where entity is provider specific for example,
+ * GPIO lines, signals, buses etc...
+ *
+ * The API allocates necessary resources and enables the timestamp. So calling
+ * hte_enable_ts is not needed. The consumer does not need to call
+ * hte_release_ts since it will be called upon consumer exit.
+ *
+ * @dev: HTE consumer/client device.
+ * @desc: Pre-allocated timestamp descriptor. HTE core will fill out necessary
+ * details. Optionally the consumer can set name field of desc, if not
+ * specified HTE core will set it as ts_con_id. It will be the consumer's
+ * job to free any allocation related to this structure as well name field
+ * in case it has set that field.
+ * @cb: Callback to push the timestamp data to consumer.
+ * @tcb: Optional callback. If its provided, subsystem will create
+ * thread. This will be called when cb returns HTE_RUN_THREADED_CB.
+ * @data: Client data, will be sent back during cb and tcb callbacks.
+ *
+ * Context: Holds mutex lock.
+ * Returns: Returns 0 on success or negative error code on failure.
+ */
+int devm_of_hte_request_ts(struct device *dev, struct hte_ts_desc *desc,
+			   hte_ts_cb_t cb, hte_ts_threaded_cb_t tcb,
+			   void *data)
+{
+	int err;
+
+	if (!dev || !dev->of_node || !desc || !cb)
+		return -EINVAL;
+
+	err = __hte_req_ts(dev, desc, cb, tcb, data);
+	if (err)
+		return err;
+
+	err = devm_add_action_or_reset(dev, __devm_hte_release_ts, desc);
+	if (err)
+		return err;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(devm_of_hte_request_ts);
+
+/**
+ * hte_req_ts_by_hte_name() - Request entity to timestamp realtime by passing
+ * property name that contains HTE provider phandle, meaning of the entity
+ * is HTE provider specific, for example lines, signals, GPIOs, buses etc...
+ *
+ * This API is designed to address below uses cases:
+ *
+ * 1) For the consumer device which acts as a central device for secondary
+ * consumers. For example, GPIO controller driver acts as a primary consumer
+ * on behalf of in kernel and userspace GPIO HTE consumers. The GPIO controller
+ * driver specifies HTE provider that it supports/wants and it becomes opaque
+ * for the secondary consumers requesting GPIO and hardware timestamp through
+ * that GPIO controller.
+ *
+ * 2) For the providers which are dependent on other hardware modules. In that
+ * case it forces consumers to go through other subsystem or driver making them
+ * secondary consumers. Same example as above applies here as well.
+ *
+ * The API allocates necessary resources and enables the timestamp. So calling
+ * hte_enable_ts is not needed.
+ *
+ * @dev: HTE consumer/client device.
+ * @propname: Name of property holding a HTE provider phandle value
+ * @desc: Pre-allocated timestamp descriptor with con_id set by the consumer.
+ * HTE core will fill out the rest. Optionally the consumer can set name
+ * field of desc, if not specified HTE core will set it as ts_con_id. It will
+ * be the consumer's job to free any allocation related to this structure as
+ * well name field in case it has set that field.
+ * @cb: Callback to push the timestamp data to consumer.
+ * @tcb: Optional callback. If its provided, subsystem will create
+ * thread. This will be called when cb returns HTE_RUN_THREADED_CB.
+ * @data: Client data, will be sent back during cb and tcb callbacks.
+ *
+ * Context: Holds mutex lock, can not be called from atomic context. The mutex
+ * lock is used to serialize multiple consumers.
+ * Returns: returns 0 on success or negative error code on failure.
+ */
+int hte_req_ts_by_hte_name(struct device *dev, const char *propname,
+			   struct hte_ts_desc *desc, hte_ts_cb_t cb,
+			   hte_ts_threaded_cb_t tcb, void *data)
+{
+	struct hte_device *gdev;
+	struct device_node *np = NULL;
+	int ret;
+	u32 xlated_id;
+
+	if (!dev->of_node || !propname || !desc)
+		return -EINVAL;
+
+	np = of_parse_phandle(dev->of_node, propname, 0);
+	if (!np)
+		return -ENODEV;
+
+	of_node_put(np);
+
+	gdev = of_node_to_htedevice(np);
+	if (IS_ERR(gdev))
+		return -ENOTSUPP;
+
+	if (!gdev->chip || !gdev->chip->ops)
+		return -ENOTSUPP;
+
+	ret = gdev->chip->xlate(gdev->chip, NULL, desc, &xlated_id);
+	if (ret < 0) {
+		dev_err(gdev->chip->dev,
+			"failed to xlate id: %d\n", desc->con_id);
+		return ret;
+	}
+
+	ret = ___hte_req_ts(gdev, desc, xlated_id, cb, tcb, data);
+	if (ret < 0) {
+		dev_err(gdev->chip->dev,
+			"failed to request id: %d\n", desc->con_id);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(hte_req_ts_by_hte_name);
+
+/**
+ * hte_get_clk_src_info() - Consumer calls this API to query clock source
+ * information of the desc.
+ *
+ * @desc: ts descriptor, same as returned from request API.
+ * @ci: The API fills this structure with the clock information data.
+ *
+ * Context: Any context.
+ * Returns: 0 on success else negative error code on failure.
+ */
+int hte_get_clk_src_info(const struct hte_ts_desc *desc,
+			 struct hte_clk_info *ci)
+{
+	struct hte_chip *chip;
+	struct hte_ts_info *ei;
+
+	if (!desc || !desc->hte_data || !ci) {
+		pr_debug("%s:%d\n", __func__, __LINE__);
+		return -EINVAL;
+	}
+
+	ei = desc->hte_data;
+	if (!ei || !ei->gdev || !ei->gdev->chip)
+		return -EINVAL;
+
+	chip = ei->gdev->chip;
+	if (!chip->ops->get_clk_src_info)
+		return -ENOTSUPP;
+
+	return chip->ops->get_clk_src_info(chip, ci);
+}
+EXPORT_SYMBOL_GPL(hte_get_clk_src_info);
+
+/**
+ * hte_push_ts_ns() - Used by the provider to push timestamp in nano
+ * seconds i.e data->tsc will be in ns.
+ *
+ * @chip: The HTE chip, used during the registration.
+ * @xlated_id: entity id understood by both subsystem and provider, usually this
+ * is obtained from xlate callback during request API.
+ * @data: timestamp data.
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+int hte_push_ts_ns(const struct hte_chip *chip, u32 xlated_id,
+		   struct hte_ts_data *data)
+{
+	hte_return_t ret;
+	int st = 0;
+	struct hte_ts_info *ei;
+	unsigned long flag;
+
+	if (!chip || !data || !chip->gdev)
+		return -EINVAL;
+
+	if (xlated_id > chip->nlines)
+		return -EINVAL;
+
+	ei = &chip->gdev->ei[xlated_id];
+
+	spin_lock_irqsave(&ei->slock, flag);
+
+	/* timestamp sequence counter */
+	data->seq = ei->seq++;
+
+	if (!test_bit(HTE_TS_REGISTERED, &ei->flags) ||
+	    test_bit(HTE_TS_DISABLE, &ei->flags)) {
+		dev_dbg(chip->dev, "Unknown timestamp push\n");
+		st = -EINVAL;
+		goto unlock;
+	}
+
+	ret = ei->cb(data, ei->cl_data);
+	if (ret == HTE_RUN_THREADED_CB && ei->thread) {
+		if (test_and_set_bit(HTE_CB_RUN_THREAD, &ei->hte_cb_flags))
+			goto unlock;
+		else
+			wake_up_process(ei->thread);
+	} else if (ret == HTE_CB_TS_DROPPED) {
+		atomic_inc(&ei->dropped_ts);
+	} else if (ret == HTE_CB_ERROR) {
+		dev_dbg(chip->dev, "cb error\n");
+	}
+
+unlock:
+	spin_unlock_irqrestore(&ei->slock, flag);
+
+	return st;
+}
+EXPORT_SYMBOL_GPL(hte_push_ts_ns);
+
+static int hte_register_chip(struct hte_chip *chip)
+{
+	struct hte_device *gdev;
+	u32 i;
+
+	if (!chip || !chip->dev || !chip->dev->of_node)
+		return -EINVAL;
+
+	if (!chip->ops || !chip->ops->request || !chip->ops->release) {
+		dev_err(chip->dev, "Driver needs to provide ops\n");
+		return -EINVAL;
+	}
+
+	gdev = kzalloc(struct_size(gdev, ei, chip->nlines), GFP_KERNEL);
+	if (!gdev)
+		return -ENOMEM;
+
+	gdev->chip = chip;
+	chip->gdev = gdev;
+	gdev->nlines = chip->nlines;
+	gdev->sdev = chip->dev;
+
+	for (i = 0; i < chip->nlines; i++) {
+		gdev->ei[i].gdev = gdev;
+		mutex_init(&gdev->ei[i].req_mlock);
+		spin_lock_init(&gdev->ei[i].slock);
+	}
+
+	if (chip->dev->driver)
+		gdev->owner = chip->dev->driver->owner;
+	else
+		gdev->owner = THIS_MODULE;
+
+	if (!chip->xlate) {
+		chip->xlate = hte_simple_xlate;
+		/* Just a id number to monitor */
+		chip->of_hte_n_cells = 1;
+	}
+
+	of_node_get(chip->dev->of_node);
+
+	INIT_LIST_HEAD(&gdev->list);
+
+	spin_lock(&hte_lock);
+	list_add_tail(&gdev->list, &hte_devices);
+	spin_unlock(&hte_lock);
+
+	hte_chip_dbgfs_init(gdev);
+
+	dev_dbg(chip->dev, "Added hte chip\n");
+
+	return 0;
+}
+
+/**
+ * hte_unregister_chip() - Used by the provider to remove a HTE chip.
+ * @chip: the HTE chip to remove.
+ *
+ * Context: Can not be called from atomic context.
+ * Returns: 0 on success or a negative error code on failure.
+ */
+static int hte_unregister_chip(struct hte_chip *chip)
+{
+	struct hte_device *gdev;
+
+	if (!chip)
+		return -EINVAL;
+
+	gdev = chip->gdev;
+
+	spin_lock(&hte_lock);
+	list_del(&gdev->list);
+	spin_unlock(&hte_lock);
+
+	gdev->chip = NULL;
+
+	of_node_put(chip->dev->of_node);
+	debugfs_remove_recursive(gdev->dbg_root);
+	kfree(gdev);
+
+	dev_dbg(chip->dev, "Removed hte chip\n");
+
+	return 0;
+}
+
+static void _hte_devm_unregister_chip(void *chip)
+{
+	hte_unregister_chip(chip);
+}
+
+/**
+ * devm_hte_register_chip() - Used by provider to register a HTE chip.
+ * @chip: the HTE chip to add to subsystem.
+ *
+ * The API is resource managed and  _hte_devm_unregister_chip will be called
+ * automatically when the provider exits.
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+int devm_hte_register_chip(struct hte_chip *chip)
+{
+	int err;
+
+	err = hte_register_chip(chip);
+	if (err)
+		return err;
+
+	err = devm_add_action_or_reset(chip->dev, _hte_devm_unregister_chip,
+				       chip);
+	if (err)
+		return err;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(devm_hte_register_chip);
diff --git a/include/linux/hte.h b/include/linux/hte.h
new file mode 100644
index 000000000000..f4dd5415a493
--- /dev/null
+++ b/include/linux/hte.h
@@ -0,0 +1,248 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 NVIDIA Corporation
+ *
+ * Author: Dipen Patel <dipenp@nvidia.com>
+ */
+
+#ifndef __LINUX_HTE_H
+#define __LINUX_HTE_H
+
+#include <linux/errno.h>
+
+struct hte_chip;
+struct hte_device;
+struct of_phandle_args;
+struct device_node;
+
+/**
+ * enum hte_dir - HTE edge timestamp direction.
+ *
+ * @HTE_RISING_EDGE_TS: Timestamps is for rising edge.
+ * @HTE_FALLING_EDGE_TS: Timestamps is for falling edge.
+ * @HTE_DIR_NOSUPP: Direction is not supported.
+ */
+enum hte_dir {
+	HTE_RISING_EDGE_TS,
+	HTE_FALLING_EDGE_TS,
+	HTE_DIR_NOSUPP,
+};
+
+/**
+ * struct hte_ts_data - HTE timestamp data.
+ * The provider uses and fills timestamp related details during push_timestamp
+ * API call. The consumer uses during retrieve_timestamp API call.
+ *
+ * @tsc: Timestamp value.
+ * @seq: Sequence counter of the timestamps.
+ * @dir: Direction of the event at the time of timestamp.
+ */
+struct hte_ts_data {
+	u64 tsc;
+	u64 seq;
+	enum hte_dir dir;
+};
+
+/**
+ * struct hte_clk_info - Clock source info that HTE provider uses to timestamp
+ * The provider uses hardware clock as a source to timestamp real time. This
+ * structure presents the clock information to consumers during
+ * hte_get_clk_src_info call.
+ *
+ * @hz: Supported clock rate in HZ, for example 1KHz clock = 1000.
+ * @type: Supported clock type. CLOCK_* types.
+ */
+struct hte_clk_info {
+	u64 hz;
+	clockid_t type;
+};
+
+/**
+ * enum hte_return- HTE subsystem return values used during callback.
+ *
+ * @HTE_CB_HANDLED: The consumer handled the data successfully.
+ * @HTE_RUN_THREADED_CB: The consumer needs further processing, in that case HTE
+ * subsystem will invoke kernel thread and call secondary callback provided by
+ * the consumer during devm_of_hte_request_ts and hte_req_ts_by_dt_node call.
+ * @HTE_CB_TS_DROPPED: The client returns when it can not store ts data.
+ * @HTE_CB_ERROR: The client returns error if anything goes wrong.
+ */
+enum hte_return {
+	HTE_CB_HANDLED,
+	HTE_RUN_THREADED_CB,
+	HTE_CB_TS_DROPPED,
+	HTE_CB_ERROR,
+};
+typedef enum hte_return hte_return_t;
+
+/**
+ * typedef hte_ts_cb_t - Callback provided during devm_of_hte_request_ts and
+ * hte_req_ts_by_dt_node APIs call.
+ *
+ * The callback is used to push timestamp data to client.
+ * @ts: HW timestamp data.
+ * @data: Client supplied data.
+ */
+typedef hte_return_t (*hte_ts_cb_t)(struct hte_ts_data *ts, void *data);
+
+/**
+ * typedef hte_ts_threaded_cb_t - Threaded callback provided during
+ * devm_of_hte_request_ts and hte_req_ts_by_dt_node APIs call.
+ *
+ * @data: Client supplied data.
+ *
+ * It will be called when client return HTE_RUN_THREADED_CB from hte_ts_cb_t.
+ * The callback will be called from thread context.
+ *
+ */
+typedef hte_return_t (*hte_ts_threaded_cb_t)(void *data);
+
+/**
+ * struct hte_ts_desc - HTE timestamp descriptor, this structure will be
+ * communication token between consumers to subsystem and subsystem to
+ * providers.
+ *
+ * @con_id: This is the same id sent in request APIs.
+ * @name: Descriptive name of the entity that is being monitored for the
+ * realtime timestamping. The consumer can set any name it likes. If null
+ * HTE core will construct name as ts_con_id. It will be the consumer's
+ * job to free any allocation if name is set by the consumer.
+ * @hte_data: Subsystem's private data relate to requested con_id.
+ */
+struct hte_ts_desc {
+	u32 con_id;
+	char *name;
+	void *hte_data;
+};
+
+/**
+ * struct hte_ops - HTE operations set by providers.
+ *
+ * @request: Hook for requesting a HTE timestamp. Returns 0 on success,
+ * non-zero for failures.
+ * @release: Hook for releasing a HTE timestamp. Returns 0 on success,
+ * non-zero for failures.
+ * @enable: Hook to enable the specified timestamp. Returns 0 on success,
+ * non-zero for failures.
+ * @disable: Hook to disable specified timestamp. Returns 0 on success,
+ * non-zero for failures.
+ * @get_clk_src_info: Hook to get the clock information the provider uses
+ * to timestamp. Returns 0 for success and negative error code for failure. On
+ * success HTE subsystem fills up provided struct hte_clk_info.
+ *
+ * xlated_id parameter is used to communicate between HTE subsystem and the
+ * providers. It is the same id returned during xlate API call and translated
+ * by the provider. This may be helpful as both subsystem and provider locate
+ * the requested entity in constant time, where entity could be anything from
+ * lines, signals, events, buses etc.. that providers support.
+ */
+struct hte_ops {
+	int (*request)(struct hte_chip *chip, u32 xlated_id);
+	int (*release)(struct hte_chip *chip, u32 xlated_id);
+	int (*enable)(struct hte_chip *chip, u32 xlated_id);
+	int (*disable)(struct hte_chip *chip, u32 xlated_id);
+	int (*get_clk_src_info)(struct hte_chip *chip,
+				struct hte_clk_info *ci);
+};
+
+/**
+ * struct hte_chip - Abstract HTE chip structure.
+ * @name: functional name of the HTE IP block.
+ * @dev: device providing the HTE.
+ * @ops: callbacks for this HTE.
+ * @nlines: number of lines/signals supported by this chip.
+ * @xlate: Callback which translates consumer supplied logical ids to
+ * physical ids, return from 0 for the success and negative for the
+ * failures. It stores (0 to @nlines) in xlated_id parameter for the success.
+ * @of_hte_n_cells: Number of cells used to form the HTE specifier.
+ * @gdev: HTE subsystem abstract device, internal to the HTE subsystem.
+ * @data: chip specific private data.
+ */
+struct hte_chip {
+	const char *name;
+	struct device *dev;
+	const struct hte_ops *ops;
+	u32 nlines;
+	int (*xlate)(struct hte_chip *gc,
+		     const struct of_phandle_args *args,
+		     struct hte_ts_desc *desc, u32 *xlated_id);
+	u8 of_hte_n_cells;
+
+	struct hte_device *gdev;
+	void *data;
+};
+
+#if IS_ENABLED(CONFIG_HTE)
+/* HTE APIs for the providers */
+int devm_hte_register_chip(struct hte_chip *chip);
+int hte_push_ts_ns(const struct hte_chip *chip, u32 xlated_id,
+		   struct hte_ts_data *data);
+
+/* HTE APIs for the consumers */
+
+int hte_release_ts(struct hte_ts_desc *desc);
+int devm_of_hte_request_ts(struct device *dev, struct hte_ts_desc *desc,
+			   hte_ts_cb_t cb, hte_ts_threaded_cb_t tcb,
+			   void *data);
+int hte_req_ts_by_hte_name(struct device *dev, const char *propname,
+			   struct hte_ts_desc *desc, hte_ts_cb_t cb,
+			   hte_ts_threaded_cb_t tcb, void *data);
+int hte_enable_ts(struct hte_ts_desc *desc);
+int hte_disable_ts(struct hte_ts_desc *desc);
+int hte_get_clk_src_info(const struct hte_ts_desc *desc,
+			 struct hte_clk_info *ci);
+
+#else /* !CONFIG_HTE */
+static inline int devm_hte_register_chip(struct hte_chip *chip)
+{
+	return -ENOTSUPP;
+}
+
+static inline int hte_push_ts_ns(const struct hte_chip *chip,
+				 u32 xlated_id,
+				 const struct hte_ts_data *data)
+{
+	return -ENOTSUPP;
+}
+
+static inline int hte_release_ts(struct hte_ts_desc *desc)
+{
+	return -ENOTSUPP;
+}
+
+static inline int devm_of_hte_request_ts(struct device *dev,
+					 struct hte_ts_desc *desc,
+					 hte_ts_cb_t cb,
+					 hte_ts_threaded_cb_t threaded_cb,
+					 void *data)
+{
+	return -ENOTSUPP;
+}
+
+static inline int hte_req_ts_by_hte_name(struct device *dev,
+					 const char *propname,
+					 struct hte_ts_desc *desc,
+					 hte_ts_cb_t cb,
+					 hte_ts_threaded_cb_t tcb, void *data)
+{
+	return -ENOTSUPP;
+}
+
+static inline int hte_enable_ts(struct hte_ts_desc *desc)
+{
+	return -ENOTSUPP;
+}
+
+static inline int hte_disable_ts(struct hte_ts_desc *desc)
+{
+	return -ENOTSUPP;
+}
+
+static inline int hte_get_clk_src_info(const struct hte_ts_desc *desc,
+				       struct hte_clk_info *ci)
+{
+	return -ENOTSUPP;
+}
+#endif /* !CONFIG_HTE */
+
+#endif
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [RFC v2 03/11] hte: Add tegra194 HTE kernel provider
  2021-09-30 23:26 [RFC v2 00/11] Intro to Hardware timestamping engine Dipen Patel
  2021-09-30 23:26 ` [RFC v2 01/11] Documentation: Add HTE subsystem guide Dipen Patel
  2021-09-30 23:26 ` [RFC v2 02/11] drivers: Add hardware timestamp engine (HTE) Dipen Patel
@ 2021-09-30 23:26 ` Dipen Patel
  2021-10-01 23:44   ` Randy Dunlap
  2021-10-02  0:07   ` Randy Dunlap
  2021-09-30 23:26 ` [RFC v2 04/11] dt-bindings: Add HTE bindings Dipen Patel
                   ` (7 subsequent siblings)
  10 siblings, 2 replies; 33+ messages in thread
From: Dipen Patel @ 2021-09-30 23:26 UTC (permalink / raw)
  To: thierry.reding, jonathanh, linux-kernel, linux-tegra, linux-gpio,
	linus.walleij, bgolaszewski, warthog618, devicetree, linux-doc,
	robh+dt
  Cc: Dipen Patel

Tegra194 device has multiple HTE instances also known as GTE
(Generic hardware Timestamping Engine) which can timestamp subset of
SoC lines/signals. This provider driver focuses on IRQ and GPIO lines
and exposes timestamping ability on those lines to the consumers
through HTE subsystem.

Also, with this patch, added:
- documentation about this provider and its capabilities at
Documentation/hte.
- Compilation support in Makefile and Kconfig

Signed-off-by: Dipen Patel <dipenp@nvidia.com>
---
 Documentation/hte/index.rst        |  22 ++
 Documentation/hte/tegra194-hte.rst |  56 +++
 Documentation/index.rst            |   1 +
 drivers/hte/Kconfig                |  12 +
 drivers/hte/Makefile               |   1 +
 drivers/hte/hte-tegra194.c         | 554 +++++++++++++++++++++++++++++
 6 files changed, 646 insertions(+)
 create mode 100644 Documentation/hte/index.rst
 create mode 100644 Documentation/hte/tegra194-hte.rst
 create mode 100644 drivers/hte/hte-tegra194.c

diff --git a/Documentation/hte/index.rst b/Documentation/hte/index.rst
new file mode 100644
index 000000000000..9f43301c05dc
--- /dev/null
+++ b/Documentation/hte/index.rst
@@ -0,0 +1,22 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+============================================
+The Linux Hardware Timestamping Engine (HTE)
+============================================
+
+The HTE Subsystem
+=================
+
+.. toctree::
+   :maxdepth: 1
+
+   hte
+
+HTE Tegra Provider
+==================
+
+.. toctree::
+   :maxdepth: 1
+
+   tegra194-hte
+
diff --git a/Documentation/hte/tegra194-hte.rst b/Documentation/hte/tegra194-hte.rst
new file mode 100644
index 000000000000..fb229bda2408
--- /dev/null
+++ b/Documentation/hte/tegra194-hte.rst
@@ -0,0 +1,56 @@
+HTE Kernel provider driver
+==========================
+
+Description
+-----------
+The Nvidia tegra194 HTE provider driver implements two GTE
+(Generic Timestamping Engine) instances 1) GPIO GTE and 2) LIC IRQ GTE. The
+both GTEs instances get the timestamp from the system counter TSC which has
+31.25MHz clock rate, and the driver converts clock tick rate to nano seconds
+before storing it as timestamp value.
+
+GPIO GTE
+--------
+
+This GTE instance timestamps GPIO in real time, for that to happen GPIO
+needs to be configured as input and IRQ needs to ba enabled. The only always on
+(AON) gpio controller instance supports timestamping GPIOs in realtime and it
+has 39 GPIO lines. The GPIO GTE and AON GPIO controller are tightly coupled as
+it requires very specific bits to be set in GPIO config register before GPIO
+GTE can be used. The GPIO GTE functionality is accessed from the GPIOLIB
+framework for the in kernel and userspace consumers. In the later case,
+requests go through GPIOLIB CDEV framework. The below APIs are added in GPIOLIB
+framework to access HTE subsystem and GPIO GTE.
+
+.. kernel-doc:: drivers/gpio/gpiolib.c
+   :functions: gpiod_req_hw_timestamp_ns gpiod_rel_hw_timestamp_ns
+
+There is hte-tegra194-gpio-test.c, located in ``drivers/hte/`` directory, test
+driver which demonstrates above APIs for the Jetson AGX platform.
+
+For userspace consumers, GPIO_V2_LINE_FLAG_EVENT_CLOCK_HARDWARE flag must be
+specifed during IOCTL calls, refer ``tools/gpio/gpio-event-mon.c``, which
+returns the timestamp in nano second.
+
+LIC IRQ GTE
+-----------
+
+This GTE instance timestamp LIC IRQ lines in real time. There are 352 IRQ
+lines which this instance can help timestamp realtime. The hte devicetree
+binding described at ``Documentation/devicetree/bindings/hte/`` gives out
+example how consumer can request IRQ line, since it is one to one mapping,
+consumers can simply specify IRQ number that they are interested in. There is
+no userspace consumer support for this GTE instance. The sample test code
+hte-tegra194-irq-test.c, located in ``drivers/hte/`` directory,
+demonstrates how to use IRQ GTE instance. The below is sample device tree
+snippet code for the test driver::
+
+ tegra_hte_irq_test {
+        compatible = "nvidia,tegra194-hte-irq-test";
+        htes = <&tegra_hte_lic 0x19>;
+        hte-names = "hte-lic";
+ };
+
+The provider source code of both IRQ and GPIO GTE instances is locate at
+``drivers/hte/hte-tegra194.c``.
+
diff --git a/Documentation/index.rst b/Documentation/index.rst
index 1b13c2445e87..b41118577fe6 100644
--- a/Documentation/index.rst
+++ b/Documentation/index.rst
@@ -138,6 +138,7 @@ needed).
    misc-devices/index
    scheduler/index
    mhi/index
+   hte/index
 
 Architecture-agnostic documentation
 -----------------------------------
diff --git a/drivers/hte/Kconfig b/drivers/hte/Kconfig
index 6fdf243d281b..bf375a5a8f8e 100644
--- a/drivers/hte/Kconfig
+++ b/drivers/hte/Kconfig
@@ -20,3 +20,15 @@ menuconfig HTE
 
 	  If unsure, say no.
 
+if HTE
+
+config HTE_TEGRA194
+	tristate "NVIDIA Tegra194 HTE Support"
+	depends on ARCH_TEGRA_194_SOC
+	help
+	  Enable this option for integrated hardware timestamping engine also
+	  known as generic timestamping engine (GTE) support on NVIDIA Tegra194
+	  systems-on-chip. The driver supports 352 LIC IRQs and 39 AON GPIOs
+	  lines for timestamping in realtime.
+
+endif
diff --git a/drivers/hte/Makefile b/drivers/hte/Makefile
index fc03bdf44427..3ae7c4029991 100644
--- a/drivers/hte/Makefile
+++ b/drivers/hte/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_HTE)		+= hte.o
+obj-$(CONFIG_HTE_TEGRA194)	+= hte-tegra194.o
 
diff --git a/drivers/hte/hte-tegra194.c b/drivers/hte/hte-tegra194.c
new file mode 100644
index 000000000000..16386e342a3c
--- /dev/null
+++ b/drivers/hte/hte-tegra194.c
@@ -0,0 +1,554 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 NVIDIA Corporation
+ *
+ * Author: Dipen Patel <dipenp@nvidia.com>
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/stat.h>
+#include <linux/interrupt.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/hte.h>
+#include <linux/uaccess.h>
+
+#define HTE_SUSPEND	0
+
+/* HTE source clock TSC is 31.25MHz */
+#define HTE_TS_CLK_RATE_HZ	31250000ULL
+#define HTE_CLK_RATE_NS		32
+#define HTE_TS_NS_SHIFT	__builtin_ctz(HTE_CLK_RATE_NS)
+
+#define NV_AON_SLICE_INVALID	-1
+#define NV_LINES_IN_SLICE	32
+
+/* AON HTE line map For slice 1 */
+#define NV_AON_HTE_SLICE1_IRQ_GPIO_28	12
+#define NV_AON_HTE_SLICE1_IRQ_GPIO_29	13
+
+/* AON HTE line map For slice 2 */
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_0	0
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_1	1
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_2	2
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_3	3
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_4	4
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_5	5
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_6	6
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_7	7
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_8	8
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_9	9
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_10	10
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_11	11
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_12	12
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_13	13
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_14	14
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_15	15
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_16	16
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_17	17
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_18	18
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_19	19
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_20	20
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_21	21
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_22	22
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_23	23
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_24	24
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_25	25
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_26	26
+#define NV_AON_HTE_SLICE2_IRQ_GPIO_27	27
+
+/* AON GPIO port AA pins */
+#define NV_AON_GPIO_PORT_AA_0		0
+#define NV_AON_GPIO_PORT_AA_1		1
+#define NV_AON_GPIO_PORT_AA_2		2
+#define NV_AON_GPIO_PORT_AA_3		3
+#define NV_AON_GPIO_PORT_AA_4		4
+#define NV_AON_GPIO_PORT_AA_5		5
+#define NV_AON_GPIO_PORT_AA_6		6
+#define NV_AON_GPIO_PORT_AA_7		7
+
+/* AON GPIO port BB pins */
+#define NV_AON_GPIO_PORT_BB_0		8
+#define NV_AON_GPIO_PORT_BB_1		9
+#define NV_AON_GPIO_PORT_BB_2		10
+#define NV_AON_GPIO_PORT_BB_3		11
+
+/* AON GPIO port CC pins */
+#define NV_AON_GPIO_PORT_CC_0		16
+#define NV_AON_GPIO_PORT_CC_1		17
+#define NV_AON_GPIO_PORT_CC_2		18
+#define NV_AON_GPIO_PORT_CC_3		19
+#define NV_AON_GPIO_PORT_CC_4		20
+#define NV_AON_GPIO_PORT_CC_5		21
+#define NV_AON_GPIO_PORT_CC_6		22
+#define NV_AON_GPIO_PORT_CC_7		23
+
+/* AON GPIO port DD pins */
+#define NV_AON_GPIO_PORT_DD_0		24
+#define NV_AON_GPIO_PORT_DD_1		25
+#define NV_AON_GPIO_PORT_DD_2		26
+
+/* AON GPIO port EE pins */
+#define NV_AON_GPIO_PORT_EE_0		32
+#define NV_AON_GPIO_PORT_EE_1		33
+#define NV_AON_GPIO_PORT_EE_2		34
+#define NV_AON_GPIO_PORT_EE_3		35
+#define NV_AON_GPIO_PORT_EE_4		36
+#define NV_AON_GPIO_PORT_EE_5		37
+#define NV_AON_GPIO_PORT_EE_6		38
+
+
+#define HTE_TECTRL		0x0
+#define HTE_TETSCH		0x4
+#define HTE_TETSCL		0x8
+#define HTE_TESRC		0xC
+#define HTE_TECCV		0x10
+#define HTE_TEPCV		0x14
+#define HTE_TECMD		0x1C
+#define HTE_TESTATUS		0x20
+#define HTE_SLICE0_TETEN	0x40
+#define HTE_SLICE1_TETEN	0x60
+
+#define HTE_SLICE_SIZE		(HTE_SLICE1_TETEN - HTE_SLICE0_TETEN)
+
+#define HTE_TECTRL_ENABLE_ENABLE	0x1
+
+#define HTE_TECTRL_OCCU_SHIFT		0x8
+#define HTE_TECTRL_INTR_SHIFT		0x1
+#define HTE_TECTRL_INTR_ENABLE		0x1
+
+#define HTE_TESRC_SLICE_SHIFT		16
+#define HTE_TESRC_SLICE_DEFAULT_MASK	0xFF
+
+#define HTE_TECMD_CMD_POP		0x1
+
+#define HTE_TESTATUS_OCCUPANCY_SHIFT	8
+#define HTE_TESTATUS_OCCUPANCY_MASK	0xFF
+
+struct hte_slices {
+	u32 r_val;
+	unsigned long flags;
+	/* to prevent lines mapped to same slice updating its register */
+	spinlock_t s_lock;
+};
+
+struct tegra_hte_line_mapped {
+	int slice;
+	u32 bit_index;
+};
+
+struct tegra_hte_line_table {
+	u32 map_sz;
+	const struct tegra_hte_line_mapped *map;
+};
+
+struct tegra_hte_soc {
+	int hte_irq;
+	u32 itr_thrshld;
+	u32 conf_rval;
+	struct hte_slices *sl;
+	const struct tegra_hte_line_table *line_map;
+	struct hte_chip *chip;
+	void __iomem *regs;
+};
+
+static const struct tegra_hte_line_mapped tegra194_aon_gpio_map[] = {
+	/* gpio, slice, bit_index */
+	[NV_AON_GPIO_PORT_AA_0]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_11},
+	[NV_AON_GPIO_PORT_AA_1]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_10},
+	[NV_AON_GPIO_PORT_AA_2]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_9},
+	[NV_AON_GPIO_PORT_AA_3]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_8},
+	[NV_AON_GPIO_PORT_AA_4]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_7},
+	[NV_AON_GPIO_PORT_AA_5]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_6},
+	[NV_AON_GPIO_PORT_AA_6]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_5},
+	[NV_AON_GPIO_PORT_AA_7]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_4},
+	[NV_AON_GPIO_PORT_BB_0]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_3},
+	[NV_AON_GPIO_PORT_BB_1]  = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_2},
+	[NV_AON_GPIO_PORT_BB_2] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_1},
+	[NV_AON_GPIO_PORT_BB_3] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_0},
+	[12] = {NV_AON_SLICE_INVALID, 0},
+	[13] = {NV_AON_SLICE_INVALID, 0},
+	[14] = {NV_AON_SLICE_INVALID, 0},
+	[15] = {NV_AON_SLICE_INVALID, 0},
+	[NV_AON_GPIO_PORT_CC_0] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_22},
+	[NV_AON_GPIO_PORT_CC_1] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_21},
+	[NV_AON_GPIO_PORT_CC_2] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_20},
+	[NV_AON_GPIO_PORT_CC_3] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_19},
+	[NV_AON_GPIO_PORT_CC_4] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_18},
+	[NV_AON_GPIO_PORT_CC_5] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_17},
+	[NV_AON_GPIO_PORT_CC_6] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_16},
+	[NV_AON_GPIO_PORT_CC_7] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_15},
+	[NV_AON_GPIO_PORT_DD_0] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_14},
+	[NV_AON_GPIO_PORT_DD_1] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_13},
+	[NV_AON_GPIO_PORT_DD_2] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_12},
+	[27] = {NV_AON_SLICE_INVALID, 0},
+	[28] = {NV_AON_SLICE_INVALID, 0},
+	[29] = {NV_AON_SLICE_INVALID, 0},
+	[30] = {NV_AON_SLICE_INVALID, 0},
+	[31] = {NV_AON_SLICE_INVALID, 0},
+	[NV_AON_GPIO_PORT_EE_0] = {1, NV_AON_HTE_SLICE1_IRQ_GPIO_29},
+	[NV_AON_GPIO_PORT_EE_1] = {1, NV_AON_HTE_SLICE1_IRQ_GPIO_28},
+	[NV_AON_GPIO_PORT_EE_2] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_27},
+	[NV_AON_GPIO_PORT_EE_3] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_26},
+	[NV_AON_GPIO_PORT_EE_4] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_25},
+	[NV_AON_GPIO_PORT_EE_5] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_24},
+	[NV_AON_GPIO_PORT_EE_6] = {2, NV_AON_HTE_SLICE2_IRQ_GPIO_23},
+};
+
+static const struct tegra_hte_line_table aon_hte_map = {
+	.map_sz = ARRAY_SIZE(tegra194_aon_gpio_map),
+	.map = tegra194_aon_gpio_map,
+};
+
+static inline u32 tegra_hte_readl(struct tegra_hte_soc *hte, u32 reg)
+{
+	return readl(hte->regs + reg);
+}
+
+static inline void tegra_hte_writel(struct tegra_hte_soc *hte, u32 reg,
+				    u32 val)
+{
+	writel(val, hte->regs + reg);
+}
+
+static inline int tegra_hte_map_to_line_id(u32 eid, struct tegra_hte_soc *gs,
+					  u32 *mapped)
+{
+	const struct tegra_hte_line_mapped *m;
+
+	if (gs->line_map) {
+		m = gs->line_map->map;
+		if (eid > gs->line_map->map_sz)
+			return -EINVAL;
+		if (m[eid].slice == NV_AON_SLICE_INVALID)
+			return -EINVAL;
+
+		*mapped = (m[eid].slice << 5) + m[eid].bit_index;
+	} else {
+		*mapped = eid;
+	}
+
+	return 0;
+}
+
+static int tegra_hte_line_xlate(struct hte_chip *gc,
+				 const struct of_phandle_args *args,
+				 struct hte_ts_desc *desc, u32 *xlated_id)
+{
+	int ret = 0;
+
+	if (!gc || !desc || !xlated_id)
+		return -EINVAL;
+
+	if (args) {
+		if (gc->of_hte_n_cells < 1)
+			return -EINVAL;
+
+		if (args->args_count != gc->of_hte_n_cells)
+			return -EINVAL;
+
+		desc->con_id = args->args[0];
+	}
+
+	ret = tegra_hte_map_to_line_id(desc->con_id, gc->data,
+				       xlated_id);
+	if (ret < 0) {
+		dev_dbg(gc->dev, "con_id:%u mapping failed\n",
+			desc->con_id);
+		return ret;
+	}
+
+	if (*xlated_id > gc->nlines)
+		return -EINVAL;
+
+	dev_dbg(gc->dev, "requested id:%u, xlated id:%u\n",
+		desc->con_id, *xlated_id);
+
+	return 0;
+}
+
+static int tegra_hte_en_dis_common(struct hte_chip *chip, u32 line_id, bool en)
+{
+	u32 slice, sl_bit_shift, line_bit, val, reg;
+	struct tegra_hte_soc *gs;
+
+	sl_bit_shift = __builtin_ctz(HTE_SLICE_SIZE);
+
+	if (!chip)
+		return -EINVAL;
+
+	gs = (struct tegra_hte_soc *)chip->data;
+
+	if (line_id > chip->nlines) {
+		dev_err(chip->dev,
+			"line id: %u is not supported by this controller\n",
+			line_id);
+		return -EINVAL;
+	}
+
+	slice = line_id >> sl_bit_shift;
+	line_bit = line_id & (HTE_SLICE_SIZE - 1);
+	reg = (slice << sl_bit_shift) + HTE_SLICE0_TETEN;
+
+	spin_lock(&gs->sl[slice].s_lock);
+
+	if (test_bit(HTE_SUSPEND, &gs->sl[slice].flags)) {
+		spin_unlock(&gs->sl[slice].s_lock);
+		dev_dbg(chip->dev, "device suspended");
+		return -EBUSY;
+	}
+
+	val = tegra_hte_readl(gs, reg);
+	if (en)
+		val = val | (1 << line_bit);
+	else
+		val = val & (~(1 << line_bit));
+	tegra_hte_writel(gs, reg, val);
+
+	spin_unlock(&gs->sl[slice].s_lock);
+
+	dev_dbg(chip->dev, "line: %u, slice %u, line_bit %u, reg:0x%x\n",
+		line_id, slice, line_bit, reg);
+
+	return 0;
+}
+
+static int tegra_hte_request(struct hte_chip *chip, u32 line_id)
+{
+	return tegra_hte_en_dis_common(chip, line_id, true);
+}
+
+static int tegra_hte_release(struct hte_chip *chip, u32 line_id)
+{
+	return tegra_hte_en_dis_common(chip, line_id, false);
+}
+
+static int tegra_hte_clk_src_info(struct hte_chip *chip,
+				  struct hte_clk_info *ci)
+{
+	(void)chip;
+
+	if (!ci)
+		return -EINVAL;
+
+	ci->hz = HTE_TS_CLK_RATE_HZ;
+	ci->type = CLOCK_MONOTONIC;
+
+	return 0;
+}
+
+static void tegra_hte_read_fifo(struct tegra_hte_soc *gs)
+{
+	u32 tsh, tsl, src, pv, cv, acv, slice, bit_index, line_id;
+	u64 tsc;
+	struct hte_ts_data el;
+
+	while ((tegra_hte_readl(gs, HTE_TESTATUS) >>
+		HTE_TESTATUS_OCCUPANCY_SHIFT) &
+		HTE_TESTATUS_OCCUPANCY_MASK) {
+		tsh = tegra_hte_readl(gs, HTE_TETSCH);
+		tsl = tegra_hte_readl(gs, HTE_TETSCL);
+		tsc = (((u64)tsh << 32) | tsl);
+
+		src = tegra_hte_readl(gs, HTE_TESRC);
+		slice = (src >> HTE_TESRC_SLICE_SHIFT) &
+			    HTE_TESRC_SLICE_DEFAULT_MASK;
+
+		pv = tegra_hte_readl(gs, HTE_TEPCV);
+		cv = tegra_hte_readl(gs, HTE_TECCV);
+		acv = pv ^ cv;
+		while (acv) {
+			bit_index = __builtin_ctz(acv);
+			el.dir = HTE_DIR_NOSUPP;
+			line_id = bit_index + (slice << 5);
+			el.tsc = tsc << HTE_TS_NS_SHIFT;
+			hte_push_ts_ns(gs->chip, line_id, &el);
+			acv &= ~BIT(bit_index);
+		}
+		tegra_hte_writel(gs, HTE_TECMD, HTE_TECMD_CMD_POP);
+	}
+}
+
+static irqreturn_t tegra_hte_isr(int irq, void *dev_id)
+{
+	struct tegra_hte_soc *gs = dev_id;
+	(void)irq;
+
+	tegra_hte_read_fifo(gs);
+
+	return IRQ_HANDLED;
+}
+
+static const struct of_device_id tegra_hte_of_match[] = {
+	{ .compatible = "nvidia,tegra194-gte-lic"},
+	{ .compatible = "nvidia,tegra194-gte-aon", .data = &aon_hte_map},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, tegra_hte_of_match);
+
+static const struct hte_ops g_ops = {
+	.request = tegra_hte_request,
+	.release = tegra_hte_release,
+	.enable = tegra_hte_request,
+	.disable = tegra_hte_release,
+	.get_clk_src_info = tegra_hte_clk_src_info,
+};
+
+static void tegra_gte_disable(void *data)
+{
+	struct platform_device *pdev = data;
+	struct tegra_hte_soc *gs = dev_get_drvdata(&pdev->dev);
+
+	tegra_hte_writel(gs, HTE_TECTRL, 0);
+}
+
+static int tegra_hte_probe(struct platform_device *pdev)
+{
+	int ret;
+	u32 i, slices, val = 0;
+	struct device *dev;
+	struct tegra_hte_soc *hte_dev;
+	struct hte_chip *gc;
+
+	dev = &pdev->dev;
+
+	hte_dev = devm_kzalloc(dev, sizeof(*hte_dev), GFP_KERNEL);
+	if (!hte_dev)
+		return -ENOMEM;
+
+	gc = devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL);
+	if (!gc)
+		return -ENOMEM;
+
+	dev_set_drvdata(&pdev->dev, hte_dev);
+	hte_dev->line_map = of_device_get_match_data(&pdev->dev);
+
+	hte_dev->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(hte_dev->regs))
+		return PTR_ERR(hte_dev->regs);
+
+	ret = of_property_read_u32(dev->of_node, "int-threshold",
+				   &hte_dev->itr_thrshld);
+	if (ret != 0)
+		hte_dev->itr_thrshld = 1;
+
+	ret = of_property_read_u32(dev->of_node, "slices", &slices);
+	if (ret != 0) {
+		dev_err(dev, "Could not read slices\n");
+		return -EINVAL;
+	}
+
+	hte_dev->sl = devm_kcalloc(dev, slices, sizeof(*hte_dev->sl),
+				   GFP_KERNEL);
+	if (!hte_dev->sl)
+		return -ENOMEM;
+
+	ret = platform_get_irq(pdev, 0);
+	if (ret < 0) {
+		dev_err_probe(dev, ret, "failed to get irq\n");
+		return ret;
+	}
+	hte_dev->hte_irq = ret;
+	ret = devm_request_irq(dev, hte_dev->hte_irq, tegra_hte_isr, 0,
+			       dev_name(dev), hte_dev);
+	if (ret < 0) {
+		dev_err(dev, "request irq failed.\n");
+		return ret;
+	}
+
+	gc->nlines = slices << 5;
+	gc->ops = &g_ops;
+	gc->dev = dev;
+	hte_dev->chip = gc;
+	gc->data = hte_dev;
+	gc->xlate = tegra_hte_line_xlate;
+	gc->of_hte_n_cells = 1;
+
+	ret = devm_hte_register_chip(hte_dev->chip);
+	if (ret) {
+		dev_err(gc->dev, "hte chip register failed");
+		return ret;
+	}
+
+	for (i = 0; i < slices; i++) {
+		hte_dev->sl[i].flags = 0;
+		spin_lock_init(&hte_dev->sl[i].s_lock);
+	}
+
+	val = HTE_TECTRL_ENABLE_ENABLE |
+	      (HTE_TECTRL_INTR_ENABLE << HTE_TECTRL_INTR_SHIFT) |
+	      (hte_dev->itr_thrshld << HTE_TECTRL_OCCU_SHIFT);
+	tegra_hte_writel(hte_dev, HTE_TECTRL, val);
+
+	ret = devm_add_action_or_reset(&pdev->dev, tegra_gte_disable, pdev);
+	if (ret)
+		return ret;
+
+	dev_dbg(gc->dev, "lines: %d, slices:%d", gc->nlines, slices);
+
+	return 0;
+}
+
+static int __maybe_unused tegra_hte_resume_early(struct device *dev)
+{
+	u32 i;
+	struct tegra_hte_soc *gs = dev_get_drvdata(dev);
+	u32 slices = gs->chip->nlines / NV_LINES_IN_SLICE;
+	u32 sl_bit_shift = __builtin_ctz(HTE_SLICE_SIZE);
+
+	tegra_hte_writel(gs, HTE_TECTRL, gs->conf_rval);
+
+	for (i = 0; i < slices; i++) {
+		spin_lock(&gs->sl[i].s_lock);
+		tegra_hte_writel(gs,
+				 ((i << sl_bit_shift) + HTE_SLICE0_TETEN),
+				 gs->sl[i].r_val);
+		clear_bit(HTE_SUSPEND, &gs->sl[i].flags);
+		spin_unlock(&gs->sl[i].s_lock);
+	}
+
+	return 0;
+}
+
+static int __maybe_unused tegra_hte_suspend_late(struct device *dev)
+{
+	u32 i;
+	struct tegra_hte_soc *gs = dev_get_drvdata(dev);
+	u32 slices = gs->chip->nlines / NV_LINES_IN_SLICE;
+	u32 sl_bit_shift = __builtin_ctz(HTE_SLICE_SIZE);
+
+	gs->conf_rval = tegra_hte_readl(gs, HTE_TECTRL);
+	for (i = 0; i < slices; i++) {
+		spin_lock(&gs->sl[i].s_lock);
+		gs->sl[i].r_val = tegra_hte_readl(gs,
+				((i << sl_bit_shift) + HTE_SLICE0_TETEN));
+		set_bit(HTE_SUSPEND, &gs->sl[i].flags);
+		spin_unlock(&gs->sl[i].s_lock);
+	}
+
+	return 0;
+}
+
+static const struct dev_pm_ops tegra_hte_pm = {
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(tegra_hte_suspend_late,
+				     tegra_hte_resume_early)
+};
+
+static struct platform_driver tegra_hte_driver = {
+	.probe = tegra_hte_probe,
+	.driver = {
+		.name = "tegra_hte",
+		.pm = &tegra_hte_pm,
+		.of_match_table = tegra_hte_of_match,
+	},
+};
+
+module_platform_driver(tegra_hte_driver);
+
+MODULE_AUTHOR("Dipen Patel <dipenp@nvidia.com>");
+MODULE_DESCRIPTION("NVIDIA Tegra HTE (Hardware Timestamping Engine) driver");
+MODULE_LICENSE("GPL v2");
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [RFC v2 04/11] dt-bindings: Add HTE bindings
  2021-09-30 23:26 [RFC v2 00/11] Intro to Hardware timestamping engine Dipen Patel
                   ` (2 preceding siblings ...)
  2021-09-30 23:26 ` [RFC v2 03/11] hte: Add tegra194 HTE kernel provider Dipen Patel
@ 2021-09-30 23:26 ` Dipen Patel
  2021-10-03 21:53   ` Linus Walleij
  2021-10-08 22:11   ` Rob Herring
  2021-09-30 23:26 ` [RFC v2 05/11] hte: Add Tegra194 IRQ HTE test driver Dipen Patel
                   ` (6 subsequent siblings)
  10 siblings, 2 replies; 33+ messages in thread
From: Dipen Patel @ 2021-09-30 23:26 UTC (permalink / raw)
  To: thierry.reding, jonathanh, linux-kernel, linux-tegra, linux-gpio,
	linus.walleij, bgolaszewski, warthog618, devicetree, linux-doc,
	robh+dt
  Cc: Dipen Patel

Introduces HTE devicetree binding details for the HTE subsystem. It
includes examples for the consumers, binding details for the providers
and specific binding details for the Tegra194 based HTE providers.

Signed-off-by: Dipen Patel <dipenp@nvidia.com>
---
Changes in v2:
- Replace hte with hardware-timestamp for property names
- Renamed file
- Removed example from the common dt binding file.

 .../hte/hardware-timestamps-common.yaml       | 29 +++++++
 .../devicetree/bindings/hte/hte-consumer.yaml | 48 +++++++++++
 .../bindings/hte/nvidia,tegra194-hte.yaml     | 79 +++++++++++++++++++
 3 files changed, 156 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/hte/hardware-timestamps-common.yaml
 create mode 100644 Documentation/devicetree/bindings/hte/hte-consumer.yaml
 create mode 100644 Documentation/devicetree/bindings/hte/nvidia,tegra194-hte.yaml

diff --git a/Documentation/devicetree/bindings/hte/hardware-timestamps-common.yaml b/Documentation/devicetree/bindings/hte/hardware-timestamps-common.yaml
new file mode 100644
index 000000000000..8b8db3bc4dcf
--- /dev/null
+++ b/Documentation/devicetree/bindings/hte/hardware-timestamps-common.yaml
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/hte/hardware-timestamps-common.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Hardware timestamp providers
+
+maintainers:
+  - Dipen Patel <dipenp@nvidia.com>
+
+description: |
+  Some devices/SoCs have hardware time stamping engines which can use hardware
+  means to timestamp entity in realtime. The entity could be anything from
+  GPIOs, IRQs, Bus and so on. The hardware timestamp engine (HTE) present
+  itself as a provider with the bindings described in this document.
+
+properties:
+  $nodename:
+    pattern: "^hardware-timestamps(@.*|-[0-9a-f])*$"
+
+  "#hardware-timestamps-cells":
+    description:
+      Number of cells in a HTE specifier.
+
+required:
+  - "#hardware-timestamps-cells"
+
+additionalProperties: true
diff --git a/Documentation/devicetree/bindings/hte/hte-consumer.yaml b/Documentation/devicetree/bindings/hte/hte-consumer.yaml
new file mode 100644
index 000000000000..cf65d1d44a18
--- /dev/null
+++ b/Documentation/devicetree/bindings/hte/hte-consumer.yaml
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/hte/hte-consumer.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: HTE Consumer Device Tree Bindings
+
+maintainers:
+  - Dipen Patel <dipenp@nvidia.com>
+
+description: |
+  HTE properties should be named "hardware-timestamps". The exact meaning of
+  each hardware-timestamps property must be documented in the device tree
+  binding for each device. An optional property "hardware-timestamps-names" may
+  contain a list of strings to label each of the HTE devices listed in the
+  "hardware-timestamps" property.
+
+  The "hardware-timestamps-names" property if specified is used to map the name
+  of the HTE device requested by the devm_of_hte_request_ts() or of_hte_request_ts
+  call to an index into the list given by the "hardware-timestamps" property.
+
+properties:
+  hardware-timestamps:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description:
+      The list of HTE provider phandle. The provider must document the number
+      of cell that must be passed in this property along with phandle.
+
+  hardware-timestamps-names:
+    $ref: /schemas/types.yaml#/definitions/string-array
+    description:
+      An optional string property.
+
+required:
+  - "hardware-timestamps"
+
+dependencies:
+  hardware-timestamps-names: [ hardware-timestamps ]
+
+additionalProperties: true
+
+examples:
+  - |
+    hte_irq_consumer {
+              hardware-timestamps = <&tegra_hte_lic 0x19>;
+              hardware-timestamps-names = "hte-irq";
+    };
diff --git a/Documentation/devicetree/bindings/hte/nvidia,tegra194-hte.yaml b/Documentation/devicetree/bindings/hte/nvidia,tegra194-hte.yaml
new file mode 100644
index 000000000000..529926118f35
--- /dev/null
+++ b/Documentation/devicetree/bindings/hte/nvidia,tegra194-hte.yaml
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/hte/nvidia,tegra194-hte.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tegra194 on chip generic hardware timestamping engine (HTE)
+
+maintainers:
+  - Dipen Patel <dipenp@nvidia.com>
+
+description: |
+  Tegra194 SoC has multiple generic hardware timestamping engines which can
+  monitor subset of GPIO and on chip IRQ lines for the state change, upon
+  detection it will record timestamp (taken from system counter) in its
+  internal hardware FIFO. It has bitmap array arranged in 32bit slices where
+  each bit represent signal/line to enable or disable for the hardware
+  timestamping.
+
+properties:
+  compatible:
+    enum:
+      - nvidia,tegra194-gte-aon
+      - nvidia,tegra194-gte-lic
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  int-threshold:
+    description:
+      HTE device generates its interrupt based on this u32 FIFO threshold
+      value. The recommended value is 1.
+    minimum: 1
+    maximum: 256
+
+  slices:
+    description:
+      HTE lines are arranged in 32 bit slice where each bit represents different
+      line/signal that it can enable/configure for the timestamp. It is u32
+      property and depends on the HTE instance in the chip.
+    enum: [3, 11]
+
+  '#hardware-timestamps-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - slices
+  - "#hardware-timestamps-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    tegra_hte_aon: hardware-timestamps@c1e0000 {
+              compatible = "nvidia,tegra194-gte-aon";
+              reg = <0xc1e0000 0x10000>;
+              interrupts = <0 13 0x4>;
+              int-threshold = <1>;
+              slices = <3>;
+              #hardware-timestamps-cells = <1>;
+    };
+
+  - |
+    tegra_hte_lic: hardware-timestamps@3aa0000 {
+              compatible = "nvidia,tegra194-gte-lic";
+              reg = <0x3aa0000 0x10000>;
+              interrupts = <0 11 0x4>;
+              int-threshold = <1>;
+              slices = <11>;
+              #hardware-timestamps-cells = <1>;
+    };
+
+...
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [RFC v2 05/11] hte: Add Tegra194 IRQ HTE test driver
  2021-09-30 23:26 [RFC v2 00/11] Intro to Hardware timestamping engine Dipen Patel
                   ` (3 preceding siblings ...)
  2021-09-30 23:26 ` [RFC v2 04/11] dt-bindings: Add HTE bindings Dipen Patel
@ 2021-09-30 23:26 ` Dipen Patel
  2021-09-30 23:26 ` [RFC v2 06/11] gpiolib: Add HTE support Dipen Patel
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 33+ messages in thread
From: Dipen Patel @ 2021-09-30 23:26 UTC (permalink / raw)
  To: thierry.reding, jonathanh, linux-kernel, linux-tegra, linux-gpio,
	linus.walleij, bgolaszewski, warthog618, devicetree, linux-doc,
	robh+dt
  Cc: Dipen Patel

Tegra194 has IRQ HTE provider which can timestamp IRQ lines in realtime
, this test driver implements consumer side which tests such provider
through HTE subsystem. During its probe, it registers sysfs interface
to easily navigate from userspace as below.

All the files are at /sys/kernel/tegra_hte_irq_test/.

- en_dis - Write only, Value 1 enables HTE line, 0 disables it

Its devicetree detail can be accessed from
Documentation/hte/tegra194-hte.rst.

This driver can be compiled as loadable module and is tested on Jetson
AGX platform using 0x19 IRQ line which belongs to i2c controller
3160000.i2c.

i2cdetect -y 1 from the userspace on this platform should be enough to
generate LIC I2C IRQ. The HTE should be able to generate
timestamps in realtime for each interrupts.

Signed-off-by: Dipen Patel <dipenp@nvidia.com>
---
 drivers/hte/Kconfig                 |   7 ++
 drivers/hte/Makefile                |   1 +
 drivers/hte/hte-tegra194-irq-test.c | 169 ++++++++++++++++++++++++++++
 3 files changed, 177 insertions(+)
 create mode 100644 drivers/hte/hte-tegra194-irq-test.c

diff --git a/drivers/hte/Kconfig b/drivers/hte/Kconfig
index bf375a5a8f8e..eb339526f141 100644
--- a/drivers/hte/Kconfig
+++ b/drivers/hte/Kconfig
@@ -31,4 +31,11 @@ config HTE_TEGRA194
 	  systems-on-chip. The driver supports 352 LIC IRQs and 39 AON GPIOs
 	  lines for timestamping in realtime.
 
+config HTE_TEGRA194_IRQ_TEST
+        tristate "NVIDIA Tegra194 HTE LIC IRQ Test"
+        depends on HTE_TEGRA194
+        help
+	  The NVIDIA Tegra194 GTE IRQ test driver demonstrates HTE subsystem
+	  usage for the LIC IRQ hardware timestamp.
+
 endif
diff --git a/drivers/hte/Makefile b/drivers/hte/Makefile
index 3ae7c4029991..75b7932c2ffc 100644
--- a/drivers/hte/Makefile
+++ b/drivers/hte/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_HTE)		+= hte.o
 obj-$(CONFIG_HTE_TEGRA194)	+= hte-tegra194.o
+obj-$(CONFIG_HTE_TEGRA194_IRQ_TEST) += hte-tegra194-irq-test.o
 
diff --git a/drivers/hte/hte-tegra194-irq-test.c b/drivers/hte/hte-tegra194-irq-test.c
new file mode 100644
index 000000000000..e43991321172
--- /dev/null
+++ b/drivers/hte/hte-tegra194-irq-test.c
@@ -0,0 +1,169 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 NVIDIA Corporation
+ *
+ * Author: Dipen Patel <dipenp@nvidia.com>
+ */
+
+#include <linux/version.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/interrupt.h>
+#include <linux/hte.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+
+/*
+ * Tegra194 On chip HTE (hardware timestamping engine) also known as GTE
+ * (generic timestamping engine) can monitor LIC (Legacy interrupt controller)
+ * IRQ lines for the event and timestamp accordingly in realtime. Follow
+ * technical reference manual for the IRQ numbers and descriptions.
+ *
+ * This sample HTE IRQ test driver demonstrating HTE API usage by enabling
+ * lic irq line in HTE to monitor and timestamp.
+ */
+
+static struct tegra_hte_test {
+	struct hte_ts_desc desc;
+	struct kobject *kobj;
+	struct device *pdev;
+} hte;
+
+static hte_return_t process_hw_ts(struct hte_ts_data *ts, void *p)
+{
+	char *edge;
+	(void)p;
+
+	if (!ts)
+		return HTE_CB_ERROR;
+
+	switch (ts->dir) {
+	case HTE_FALLING_EDGE_TS:
+		edge = "falling";
+		break;
+	case HTE_RISING_EDGE_TS:
+		edge = "rising";
+		break;
+	default:
+		edge = "unknown";
+		break;
+	}
+
+	dev_info(hte.pdev, "IRQ HW timestamp(%llu): %llu, edge: %s\n",
+		 ts->seq, ts->tsc, edge);
+
+	return HTE_CB_HANDLED;
+}
+
+/*
+ * Sysfs attribute to request/release HTE IRQ line.
+ */
+static ssize_t store_en_dis(struct kobject *kobj,
+			    struct kobj_attribute *attr,
+			    const char *buf, size_t count)
+{
+	int ret = count;
+	unsigned long val = 0;
+	struct hte_clk_info ci;
+	(void)kobj;
+	(void)attr;
+
+	if (kstrtoul(buf, 10, &val) < 0) {
+		ret = -EINVAL;
+		goto error;
+	}
+
+	if (val == 1) {
+		ret = devm_of_hte_request_ts(hte.pdev, &hte.desc,
+					     process_hw_ts, NULL, NULL);
+		if (ret)
+			goto error;
+
+		hte_get_clk_src_info(&hte.desc, &ci);
+		dev_info(hte.pdev, "clk rate:%llu, clk type: %d\n",
+			 ci.hz, ci.type);
+	} else if (val == 0) {
+		ret = hte_release_ts(&hte.desc);
+		if (ret)
+			goto error;
+	}
+
+	ret = count;
+
+error:
+	return ret;
+}
+
+struct kobj_attribute en_dis_attr =
+		__ATTR(en_dis, 0220, NULL, store_en_dis);
+
+static struct attribute *attrs[] = {
+	&en_dis_attr.attr,
+	NULL,
+};
+
+static struct attribute_group tegra_hte_test_attr_group = {
+	.attrs = attrs,
+};
+
+static int tegra_hte_test_sysfs_create(void)
+{
+	int ret;
+
+	/* Creates /sys/kernel/tegra_hte_irq_test */
+	hte.kobj = kobject_create_and_add("tegra_hte_irq_test", kernel_kobj);
+	if (!hte.kobj)
+		return -ENOMEM;
+
+	ret = sysfs_create_group(hte.kobj, &tegra_hte_test_attr_group);
+	if (ret)
+		kobject_put(hte.kobj);
+
+	return ret;
+}
+
+static const struct of_device_id tegra_hte_irq_test_of_match[] = {
+	{ .compatible = "nvidia,tegra194-hte-irq-test"},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, tegra_hte_irq_test_of_match);
+
+static int tegra_hte_test_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	dev_set_drvdata(&pdev->dev, &hte);
+	hte.pdev = &pdev->dev;
+
+	ret = tegra_hte_test_sysfs_create();
+	if (ret != 0) {
+		dev_err(hte.pdev, "sysfs creation failed\n");
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+static int tegra_hte_test_remove(struct platform_device *pdev)
+{
+	(void)pdev;
+
+	kobject_put(hte.kobj);
+
+	return 0;
+}
+
+static struct platform_driver tegra_hte_irq_test_driver = {
+	.probe = tegra_hte_test_probe,
+	.remove = tegra_hte_test_remove,
+	.driver = {
+		.name = "tegra_hte_irq_test",
+		.of_match_table = tegra_hte_irq_test_of_match,
+	},
+};
+module_platform_driver(tegra_hte_irq_test_driver);
+
+MODULE_AUTHOR("Dipen Patel <dipenp@nvidia.com>");
+MODULE_LICENSE("GPL v2");
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [RFC v2 06/11] gpiolib: Add HTE support
  2021-09-30 23:26 [RFC v2 00/11] Intro to Hardware timestamping engine Dipen Patel
                   ` (4 preceding siblings ...)
  2021-09-30 23:26 ` [RFC v2 05/11] hte: Add Tegra194 IRQ HTE test driver Dipen Patel
@ 2021-09-30 23:26 ` Dipen Patel
  2021-10-01  9:19   ` kernel test robot
  2021-10-03 22:01   ` Linus Walleij
  2021-09-30 23:26 ` [RFC v2 07/11] gpio: tegra186: Add HTE in gpio-tegra186 driver Dipen Patel
                   ` (4 subsequent siblings)
  10 siblings, 2 replies; 33+ messages in thread
From: Dipen Patel @ 2021-09-30 23:26 UTC (permalink / raw)
  To: thierry.reding, jonathanh, linux-kernel, linux-tegra, linux-gpio,
	linus.walleij, bgolaszewski, warthog618, devicetree, linux-doc,
	robh+dt
  Cc: Dipen Patel

Some GPIO chip can provide hardware timestamp support on its GPIO lines
, in order to support that additional API needs to be added which
can talk to both GPIO chip and HTE (hardware timestamping engine)
subsystem. This patch introduces APIs which gpio consumer can use
to request hardware assisted timestamping. Below is the list of the APIs
that are added in gpiolib subsystem.

- gpiod_req_hw_timestamp_ns - Request HTE on specified GPIO line.
- gpiod_rel_hw_timestamp_ns - Release HTE functionality on GPIO line.

Signed-off-by: Dipen Patel <dipenp@nvidia.com>
---
Changes in v2:
- removed get timestamp and is timestamp enabled APIs

 drivers/gpio/gpiolib.c        | 73 +++++++++++++++++++++++++++++++++++
 drivers/gpio/gpiolib.h        | 12 ++++++
 include/linux/gpio/consumer.h | 19 ++++++++-
 include/linux/gpio/driver.h   | 14 +++++++
 4 files changed, 116 insertions(+), 2 deletions(-)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index d1b9b721218f..781d685cc2de 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1971,6 +1971,10 @@ static bool gpiod_free_commit(struct gpio_desc *desc)
 			gc->free(gc, gpio_chip_hwgpio(desc));
 			spin_lock_irqsave(&gpio_lock, flags);
 		}
+		spin_unlock_irqrestore(&gpio_lock, flags);
+		gpiod_rel_hw_timestamp_ns(desc);
+		spin_lock_irqsave(&gpio_lock, flags);
+
 		kfree_const(desc->label);
 		desc_set_label(desc, NULL);
 		clear_bit(FLAG_ACTIVE_LOW, &desc->flags);
@@ -2383,6 +2387,75 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)
 }
 EXPORT_SYMBOL_GPL(gpiod_direction_output);
 
+/**
+ * gpiod_req_hw_timestamp_ns - Enable the hardware assisted timestamp in
+ * nano second.
+ *
+ * @desc: GPIO to enable
+ * @cb:	Callback, will be called when HTE pushes timestamp data.
+ * @tcb: Threaeded callback, it gets called from kernel thread context and when
+ * cb returns with HTE_RUN_THREADED_CB return value.
+ * @data: Client data, will be sent back with tcb and cb.
+ *
+ * Certain GPIO chip can rely on hardware assisted timestamp engines which can
+ * record timestamp at the occurance of the configured events
+ * i.e. rising/falling on specified GPIO lines. This is helper API to enable hw
+ * assisted timestamp in nano second.
+ *
+ * Return 0 in case of success, else an error code.
+ */
+int gpiod_req_hw_timestamp_ns(struct gpio_desc *desc, hte_ts_cb_t cb,
+			      hte_ts_threaded_cb_t tcb, void *data)
+{
+	struct gpio_chip *gc;
+	int ret = 0;
+
+	VALIDATE_DESC(desc);
+	gc = desc->gdev->chip;
+
+	if (!gc->req_hw_timestamp) {
+		gpiod_warn(desc, "%s: hw ts not supported\n", __func__);
+		return -ENOTSUPP;
+	}
+
+	ret = gc->req_hw_timestamp(gc, gpio_chip_hwgpio(desc), cb, tcb,
+				   &desc->hdesc, data);
+	if (ret)
+		gpiod_warn(desc, "%s: hw ts request failed\n", __func__);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(gpiod_req_hw_timestamp_ns);
+
+/**
+ * gpiod_rel_hw_timestamp_ns - Release and disable the hardware assisted
+ * timestamp.
+ *
+ * @desc: GPIO to disable
+ *
+ * Return 0 in case of success, else an error code.
+ */
+int gpiod_rel_hw_timestamp_ns(struct gpio_desc *desc)
+{
+	struct gpio_chip *gc;
+	int ret = 0;
+
+	VALIDATE_DESC(desc);
+	gc = desc->gdev->chip;
+
+	if (!gc->rel_hw_timestamp) {
+		gpiod_warn(desc, "%s: hw ts not supported\n", __func__);
+		return -ENOTSUPP;
+	}
+
+	ret = gc->rel_hw_timestamp(gc, gpio_chip_hwgpio(desc), &desc->hdesc);
+	if (ret)
+		gpiod_warn(desc, "%s: hw ts release failed\n", __func__);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(gpiod_rel_hw_timestamp_ns);
+
 /**
  * gpiod_set_config - sets @config for a GPIO
  * @desc: descriptor of the GPIO for which to set the configuration
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index 30bc3f80f83e..f634b9de3756 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -15,6 +15,7 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/cdev.h>
+#include <linux/hte.h>
 
 #define GPIOCHIP_NAME	"gpiochip"
 
@@ -117,6 +118,7 @@ struct gpio_desc {
 #define FLAG_EDGE_RISING     16	/* GPIO CDEV detects rising edge events */
 #define FLAG_EDGE_FALLING    17	/* GPIO CDEV detects falling edge events */
 #define FLAG_EVENT_CLOCK_REALTIME	18 /* GPIO CDEV reports REALTIME timestamps in events */
+#define FLAG_EVENT_CLOCK_HARDWARE	19 /* GPIO CDEV reports hardware timestamps in events */
 
 	/* Connection label */
 	const char		*label;
@@ -129,6 +131,16 @@ struct gpio_desc {
 	/* debounce period in microseconds */
 	unsigned int		debounce_period_us;
 #endif
+	/*
+	 * Hardware timestamp engine related internal data structure.
+	 * This gets filled out when the consumer calls
+	 * gpiod_req_hw_timestamp_ns to enable hardware timestamping on the
+	 * specified GPIO line. The API calls into HTE subsystem which
+	 * initializes appropriate field of the hdesc. The hdesc will be later
+	 * used with gpiod_rel_hw_timestamp to release hw timestamp
+	 * functionality.
+	 */
+	struct hte_ts_desc hdesc;
 };
 
 #define gpiod_not_found(desc)		(IS_ERR(desc) && PTR_ERR(desc) == -ENOENT)
diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
index 97a28ad3393b..e6f17083ca0a 100644
--- a/include/linux/gpio/consumer.h
+++ b/include/linux/gpio/consumer.h
@@ -6,6 +6,7 @@
 #include <linux/bug.h>
 #include <linux/compiler_types.h>
 #include <linux/err.h>
+#include <linux/hte.h>
 
 struct device;
 
@@ -112,6 +113,9 @@ int gpiod_get_direction(struct gpio_desc *desc);
 int gpiod_direction_input(struct gpio_desc *desc);
 int gpiod_direction_output(struct gpio_desc *desc, int value);
 int gpiod_direction_output_raw(struct gpio_desc *desc, int value);
+int gpiod_req_hw_timestamp_ns(struct gpio_desc *desc, hte_ts_cb_t cb,
+			      hte_ts_threaded_cb_t tcb, void *data);
+int gpiod_rel_hw_timestamp_ns(struct gpio_desc *desc);
 
 /* Value get/set from non-sleeping context */
 int gpiod_get_value(const struct gpio_desc *desc);
@@ -353,8 +357,19 @@ static inline int gpiod_direction_output_raw(struct gpio_desc *desc, int value)
 	WARN_ON(desc);
 	return -ENOSYS;
 }
-
-
+static inline int gpiod_req_hw_timestamp_ns(struct gpio_desc *desc,
+					    hte_ts_cb_t cb,
+					    hte_ts_threaded tcb,
+					    void *data)
+{
+	WARN_ON(desc);
+	return -ENOSYS;
+}
+static inline int gpiod_rel_hw_timestamp_ns(struct gpio_desc *desc)
+{
+	WARN_ON(desc);
+	return -ENOSYS;
+}
 static inline int gpiod_get_value(const struct gpio_desc *desc)
 {
 	/* GPIO can never have been requested */
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
index a0f9901dcae6..5dc6c941dbe0 100644
--- a/include/linux/gpio/driver.h
+++ b/include/linux/gpio/driver.h
@@ -10,6 +10,7 @@
 #include <linux/lockdep.h>
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/pinctrl/pinconf-generic.h>
+#include <linux/hte.h> /* For hardware timestamping */
 
 struct gpio_desc;
 struct of_phandle_args;
@@ -304,6 +305,10 @@ struct gpio_irq_chip {
  * @add_pin_ranges: optional routine to initialize pin ranges, to be used when
  *	requires special mapping of the pins that provides GPIO functionality.
  *	It is called after adding GPIO chip and before adding IRQ chip.
+ * @req_hw_timestamp: Dependent on GPIO chip, an optional routine to
+ *	enable hardware assisted timestamp.
+ * @rel_hw_timestamp: Dependent on GPIO chip, an optional routine to
+ *	disable/release hardware assisted timestamp.
  * @base: identifies the first GPIO number handled by this chip;
  *	or, if negative during registration, requests dynamic ID allocation.
  *	DEPRECATION: providing anything non-negative and nailing the base
@@ -399,6 +404,15 @@ struct gpio_chip {
 
 	int			(*add_pin_ranges)(struct gpio_chip *gc);
 
+	int			(*req_hw_timestamp)(struct gpio_chip *gc,
+						    unsigned int offset,
+						    hte_ts_cb_t cb,
+						    hte_ts_threaded_cb_t tcb,
+						    struct hte_ts_desc *hdesc,
+						    void *data);
+	int			(*rel_hw_timestamp)(struct gpio_chip *chip,
+						    unsigned int offset,
+						    struct hte_ts_desc *hdesc);
 	int			base;
 	u16			ngpio;
 	u16			offset;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [RFC v2 07/11] gpio: tegra186: Add HTE in gpio-tegra186 driver
  2021-09-30 23:26 [RFC v2 00/11] Intro to Hardware timestamping engine Dipen Patel
                   ` (5 preceding siblings ...)
  2021-09-30 23:26 ` [RFC v2 06/11] gpiolib: Add HTE support Dipen Patel
@ 2021-09-30 23:26 ` Dipen Patel
  2021-10-08 22:16   ` Rob Herring
  2021-09-30 23:26 ` [RFC v2 08/11] gpiolib: cdev: Add hardware timestamp clock type Dipen Patel
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 33+ messages in thread
From: Dipen Patel @ 2021-09-30 23:26 UTC (permalink / raw)
  To: thierry.reding, jonathanh, linux-kernel, linux-tegra, linux-gpio,
	linus.walleij, bgolaszewski, warthog618, devicetree, linux-doc,
	robh+dt
  Cc: Dipen Patel

Tegra194 AON GPIO controller with the use of its internal hardware
timestamping engine (HTE) also known as GTE can timestamp GPIO
lines through system counter. This patch implements two callbacks
which are essential for the gpio consumers that want such HTE
functionality. The callbacks details can be found at
include/gpio/driver.h.

Since AON GPIO controller depends on HTE engine, it creates hardware
dependency between controller and AON HTE provider. To express that,
the optional devicetree property is introduced for AON GPIO controller.

Signed-off-by: Dipen Patel <dipenp@nvidia.com>
---
 .../bindings/gpio/nvidia,tegra186-gpio.txt    |  7 ++
 drivers/gpio/gpio-tegra186.c                  | 89 +++++++++++++++++++
 2 files changed, 96 insertions(+)

diff --git a/Documentation/devicetree/bindings/gpio/nvidia,tegra186-gpio.txt b/Documentation/devicetree/bindings/gpio/nvidia,tegra186-gpio.txt
index adff16c71d21..00a3e47ab560 100644
--- a/Documentation/devicetree/bindings/gpio/nvidia,tegra186-gpio.txt
+++ b/Documentation/devicetree/bindings/gpio/nvidia,tegra186-gpio.txt
@@ -127,6 +127,12 @@ Required properties:
             - 8: Active low level-sensitive.
             Valid combinations are 1, 2, 3, 4, 8.
 
+Optional properties:
+- timestamp-engine
+    AON GPIO controller has timestamp engine which can hardware timestamp
+    GPIO configured as input and IRQ. This property specifies hardware
+    timestamp engine (HTE) device-tree node.
+
 Example:
 
 #include <dt-bindings/interrupt-controller/irq.h>
@@ -162,4 +168,5 @@ gpio@c2f0000 {
 	#gpio-cells = <2>;
 	interrupt-controller;
 	#interrupt-cells = <2>;
+	timestamp-engine = <&tegra_hte_aon>;
 };
diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c
index c026e7141e4e..6d1f15167529 100644
--- a/drivers/gpio/gpio-tegra186.c
+++ b/drivers/gpio/gpio-tegra186.c
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/hte.h>
 
 #include <dt-bindings/gpio/tegra186-gpio.h>
 #include <dt-bindings/gpio/tegra194-gpio.h>
@@ -34,6 +35,7 @@
 #define  TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_LEVEL BIT(4)
 #define  TEGRA186_GPIO_ENABLE_CONFIG_DEBOUNCE BIT(5)
 #define  TEGRA186_GPIO_ENABLE_CONFIG_INTERRUPT BIT(6)
+#define  TEGRA186_GPIO_ENABLE_CONFIG_TIMESTAMP_FUNC BIT(7)
 
 #define TEGRA186_GPIO_DEBOUNCE_CONTROL 0x04
 #define  TEGRA186_GPIO_DEBOUNCE_CONTROL_THRESHOLD(x) ((x) & 0xff)
@@ -81,6 +83,7 @@ struct tegra_gpio {
 	struct irq_chip intc;
 	unsigned int num_irq;
 	unsigned int *irq;
+	struct device *dev;
 
 	const struct tegra_gpio_soc *soc;
 	unsigned int num_irqs_per_bank;
@@ -192,6 +195,86 @@ static int tegra186_gpio_direction_output(struct gpio_chip *chip,
 	return 0;
 }
 
+static int tegra186_gpio_req_hw_ts(struct gpio_chip *chip, unsigned int offset,
+				   hte_ts_cb_t cb, hte_ts_threaded_cb_t tcb,
+				   struct hte_ts_desc *hdesc, void *data)
+{
+	struct tegra_gpio *gpio;
+	void __iomem *base;
+	int value, ret;
+
+	if (!chip || !hdesc)
+		return -EINVAL;
+
+	gpio = gpiochip_get_data(chip);
+	if (!gpio)
+		return -ENODEV;
+
+	base = tegra186_gpio_get_base(gpio, offset);
+	if (WARN_ON(base == NULL))
+		return -EINVAL;
+
+	/*
+	 * HTE provider of this gpio controller does not support below gpio
+	 * configs:
+	 * 1. gpio as output
+	 * 2. gpio as input
+	 *
+	 * HTE provider supports below gpio config:
+	 * a. gpio as input with irq enabled
+	 */
+
+	if (tegra186_gpio_get_direction(chip, offset) ==
+	    GPIO_LINE_DIRECTION_OUT)
+		return -ENOTSUPP;
+
+	if (!gpiochip_line_is_irq(chip, offset))
+		return -ENOTSUPP;
+
+	hdesc->con_id = offset;
+
+	ret = hte_req_ts_by_hte_name(gpio->dev, "timestamp-engine", hdesc, cb,
+				     tcb, data);
+	if (ret)
+		return ret;
+
+	value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG);
+	value |= TEGRA186_GPIO_ENABLE_CONFIG_TIMESTAMP_FUNC;
+	writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG);
+
+	return 0;
+}
+
+static int tegra186_gpio_rel_hw_ts(struct gpio_chip *chip,
+				   unsigned int offset,
+				   struct hte_ts_desc *hdesc)
+{
+	struct tegra_gpio *gpio;
+	void __iomem *base;
+	int value, ret;
+
+	if (!hdesc || !chip)
+		return -EINVAL;
+
+	gpio = gpiochip_get_data(chip);
+	if (!gpio)
+		return -ENODEV;
+
+	base = tegra186_gpio_get_base(gpio, offset);
+	if (WARN_ON(base == NULL))
+		return -EINVAL;
+
+	ret = hte_release_ts(hdesc);
+	if (ret)
+		return ret;
+
+	value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG);
+	value &= ~TEGRA186_GPIO_ENABLE_CONFIG_TIMESTAMP_FUNC;
+	writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG);
+
+	return 0;
+}
+
 static int tegra186_gpio_get(struct gpio_chip *chip, unsigned int offset)
 {
 	struct tegra_gpio *gpio = gpiochip_get_data(chip);
@@ -821,6 +904,12 @@ static int tegra186_gpio_probe(struct platform_device *pdev)
 		offset += port->pins;
 	}
 
+	gpio->dev = &pdev->dev;
+	if (device_property_present(gpio->dev, "timestamp-engine")) {
+		gpio->gpio.req_hw_timestamp = tegra186_gpio_req_hw_ts;
+		gpio->gpio.rel_hw_timestamp = tegra186_gpio_rel_hw_ts;
+	}
+
 	return devm_gpiochip_add_data(&pdev->dev, &gpio->gpio, gpio);
 }
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [RFC v2 08/11] gpiolib: cdev: Add hardware timestamp clock type
  2021-09-30 23:26 [RFC v2 00/11] Intro to Hardware timestamping engine Dipen Patel
                   ` (6 preceding siblings ...)
  2021-09-30 23:26 ` [RFC v2 07/11] gpio: tegra186: Add HTE in gpio-tegra186 driver Dipen Patel
@ 2021-09-30 23:26 ` Dipen Patel
  2021-10-03 21:59   ` Linus Walleij
  2021-10-03 22:09   ` Linus Walleij
  2021-09-30 23:26 ` [RFC v2 09/11] tools: gpio: Add new hardware " Dipen Patel
                   ` (2 subsequent siblings)
  10 siblings, 2 replies; 33+ messages in thread
From: Dipen Patel @ 2021-09-30 23:26 UTC (permalink / raw)
  To: thierry.reding, jonathanh, linux-kernel, linux-tegra, linux-gpio,
	linus.walleij, bgolaszewski, warthog618, devicetree, linux-doc,
	robh+dt
  Cc: Dipen Patel

This patch adds new clock type for the GPIO controller which can
timestamp gpio lines in realtime using hardware means. To expose such
functionalities to the userspace, code has been added in this patch
where during line create call, it checks for new clock type and if
requested, calls hardware timestamp related API from gpiolib.c.
During line change event, the HTE subsystem pushes timestamp data
through callbacks.

Signed-off-by: Dipen Patel <dipenp@nvidia.com>
---
Changes in v2:
- Added hte_dir and static structure hte_ts_desc.
- Added callbacks which get invoked by HTE when new data is available.
- Better use of hte_dir and seq from hte_ts_desc.
- Modified sw debounce function to accommodate hardware timestamping.

 drivers/gpio/gpiolib-cdev.c | 161 ++++++++++++++++++++++++++++++++++--
 include/uapi/linux/gpio.h   |   1 +
 2 files changed, 153 insertions(+), 9 deletions(-)

diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
index c7b5446d01fd..1736ad54e3ec 100644
--- a/drivers/gpio/gpiolib-cdev.c
+++ b/drivers/gpio/gpiolib-cdev.c
@@ -464,6 +464,12 @@ struct line {
 	 * stale value.
 	 */
 	unsigned int level;
+	/*
+	 * dir will be touched in HTE callbacks hte_ts_cb_t and
+	 * hte_ts_threaded_cb_t and they are mutually exclusive. This will be
+	 * unused when HTE is not supported/disabled.
+	 */
+	enum hte_dir dir;
 };
 
 /**
@@ -518,6 +524,7 @@ struct linereq {
 	 GPIO_V2_LINE_DRIVE_FLAGS | \
 	 GPIO_V2_LINE_EDGE_FLAGS | \
 	 GPIO_V2_LINE_FLAG_EVENT_CLOCK_REALTIME | \
+	 GPIO_V2_LINE_FLAG_EVENT_CLOCK_HARDWARE | \
 	 GPIO_V2_LINE_BIAS_FLAGS)
 
 static void linereq_put_event(struct linereq *lr,
@@ -546,6 +553,94 @@ static u64 line_event_timestamp(struct line *line)
 	return ktime_get_ns();
 }
 
+static hte_return_t process_hw_ts_thread(void *p)
+{
+	struct line *line = p;
+	struct linereq *lr = line->req;
+	struct gpio_v2_line_event le;
+	u64 eflags;
+
+	memset(&le, 0, sizeof(le));
+
+	le.timestamp_ns = line->timestamp_ns;
+	line->timestamp_ns = 0;
+
+	if (line->dir >= HTE_DIR_NOSUPP) {
+		eflags = READ_ONCE(line->eflags);
+		if (eflags == GPIO_V2_LINE_FLAG_EDGE_BOTH) {
+			int level = gpiod_get_value_cansleep(line->desc);
+
+			if (level)
+				/* Emit low-to-high event */
+				le.id = GPIO_V2_LINE_EVENT_RISING_EDGE;
+			else
+				/* Emit high-to-low event */
+				le.id = GPIO_V2_LINE_EVENT_FALLING_EDGE;
+		} else if (eflags == GPIO_V2_LINE_FLAG_EDGE_RISING) {
+			/* Emit low-to-high event */
+			le.id = GPIO_V2_LINE_EVENT_RISING_EDGE;
+		} else if (eflags == GPIO_V2_LINE_FLAG_EDGE_FALLING) {
+			/* Emit high-to-low event */
+			le.id = GPIO_V2_LINE_EVENT_FALLING_EDGE;
+		} else {
+			return HTE_CB_ERROR;
+		}
+	} else {
+		if (line->dir == HTE_RISING_EDGE_TS)
+			le.id = GPIO_V2_LINE_EVENT_RISING_EDGE;
+		else
+			le.id = GPIO_V2_LINE_EVENT_FALLING_EDGE;
+	}
+
+	le.line_seqno = line->line_seqno;
+	le.seqno = (lr->num_lines == 1) ? le.line_seqno : line->req_seqno;
+	le.offset = gpio_chip_hwgpio(line->desc);
+
+	linereq_put_event(lr, &le);
+
+	return HTE_CB_HANDLED;
+}
+
+static hte_return_t process_hw_ts(struct hte_ts_data *ts, void *p)
+{
+	struct line *line = p;
+	struct linereq *lr = line->req;
+
+	if (!ts)
+		return HTE_CB_ERROR;
+
+	line->timestamp_ns = ts->tsc;
+	line->dir = ts->dir;
+
+	/*
+	 * It is possible that HTE engine detects spurious edges for the
+	 * lines where software debounce is enabled. This primary callback
+	 * will be called multiple times in that case. It will be better to
+	 * let debounce_work_func handle instead of process_hw_ts_thread.
+	 * The timestamp_ns will be overwritten here which is fine as we are
+	 * interested in the last value anyway. The debounce_work_func will
+	 * then just read whatever last line->timestamp_ns is stored. Because
+	 * this callback can be called multiple times, we are not really
+	 * interested in ts->seq.
+	 */
+	if (!READ_ONCE(line->sw_debounced)) {
+		line->line_seqno = ts->seq;
+
+		/*
+		 * Increment in this callback incase all the lines in linereq
+		 * are enabled for hw timestamping. This will work even if
+		 * subset of lines are enabled for hw timestamping as
+		 * edge_irq_* callbacks will proceed as usual for them.
+		 */
+		if (lr->num_lines != 1)
+			line->req_seqno = atomic_inc_return(&lr->seqno);
+
+		return HTE_RUN_THREADED_CB;
+	}
+
+	return HTE_CB_HANDLED;
+}
+
 static irqreturn_t edge_irq_thread(int irq, void *p)
 {
 	struct line *line = p;
@@ -553,6 +648,10 @@ static irqreturn_t edge_irq_thread(int irq, void *p)
 	struct gpio_v2_line_event le;
 	u64 eflags;
 
+	/* Let process_hw_ts_thread handle */
+	if (test_bit(FLAG_EVENT_CLOCK_HARDWARE, &line->desc->flags))
+		return IRQ_HANDLED;
+
 	/* Do not leak kernel stack to userspace */
 	memset(&le, 0, sizeof(le));
 
@@ -604,6 +703,10 @@ static irqreturn_t edge_irq_handler(int irq, void *p)
 	struct line *line = p;
 	struct linereq *lr = line->req;
 
+	/* Let HTE supplied callbacks handle */
+	if (test_bit(FLAG_EVENT_CLOCK_HARDWARE, &line->desc->flags))
+		return IRQ_HANDLED;
+
 	/*
 	 * Just store the timestamp in hardirq context so we get it as
 	 * close in time as possible to the actual event.
@@ -682,14 +785,6 @@ static void debounce_work_func(struct work_struct *work)
 	/* Do not leak kernel stack to userspace */
 	memset(&le, 0, sizeof(le));
 
-	lr = line->req;
-	le.timestamp_ns = line_event_timestamp(line);
-	le.offset = gpio_chip_hwgpio(line->desc);
-	line->line_seqno++;
-	le.line_seqno = line->line_seqno;
-	le.seqno = (lr->num_lines == 1) ?
-		le.line_seqno : atomic_inc_return(&lr->seqno);
-
 	if (level)
 		/* Emit low-to-high event */
 		le.id = GPIO_V2_LINE_EVENT_RISING_EDGE;
@@ -697,6 +792,23 @@ static void debounce_work_func(struct work_struct *work)
 		/* Emit high-to-low event */
 		le.id = GPIO_V2_LINE_EVENT_FALLING_EDGE;
 
+	if (test_bit(FLAG_EVENT_CLOCK_HARDWARE, &line->desc->flags)) {
+		le.timestamp_ns = line->timestamp_ns;
+		if (line->dir < HTE_DIR_NOSUPP)
+			le.id = (line->dir == HTE_RISING_EDGE_TS) ?
+				 GPIO_V2_LINE_EVENT_RISING_EDGE :
+				 GPIO_V2_LINE_EVENT_FALLING_EDGE;
+	} else {
+		le.timestamp_ns = line_event_timestamp(line);
+	}
+
+	lr = line->req;
+	le.offset = gpio_chip_hwgpio(line->desc);
+	line->line_seqno++;
+	le.line_seqno = line->line_seqno;
+	le.seqno = (lr->num_lines == 1) ?
+		le.line_seqno : atomic_inc_return(&lr->seqno);
+
 	linereq_put_event(lr, &le);
 }
 
@@ -891,7 +1003,6 @@ static int gpio_v2_line_flags_validate(u64 flags)
 	/* Return an error if an unknown flag is set */
 	if (flags & ~GPIO_V2_LINE_VALID_FLAGS)
 		return -EINVAL;
-
 	/*
 	 * Do not allow both INPUT and OUTPUT flags to be set as they are
 	 * contradictory.
@@ -900,6 +1011,11 @@ static int gpio_v2_line_flags_validate(u64 flags)
 	    (flags & GPIO_V2_LINE_FLAG_OUTPUT))
 		return -EINVAL;
 
+	/* Only allow one event clock source */
+	if ((flags & GPIO_V2_LINE_FLAG_EVENT_CLOCK_REALTIME) &&
+	    (flags & GPIO_V2_LINE_FLAG_EVENT_CLOCK_HARDWARE))
+		return -EINVAL;
+
 	/* Edge detection requires explicit input. */
 	if ((flags & GPIO_V2_LINE_EDGE_FLAGS) &&
 	    !(flags & GPIO_V2_LINE_FLAG_INPUT))
@@ -992,6 +1108,8 @@ static void gpio_v2_line_config_flags_to_desc_flags(u64 flags,
 
 	assign_bit(FLAG_EVENT_CLOCK_REALTIME, flagsp,
 		   flags & GPIO_V2_LINE_FLAG_EVENT_CLOCK_REALTIME);
+	assign_bit(FLAG_EVENT_CLOCK_HARDWARE, flagsp,
+		   flags & GPIO_V2_LINE_FLAG_EVENT_CLOCK_HARDWARE);
 }
 
 static long linereq_get_values(struct linereq *lr, void __user *ip)
@@ -1154,6 +1272,21 @@ static long linereq_set_config_unlocked(struct linereq *lr,
 				return ret;
 		}
 
+		/* Check if new config sets hardware assisted clock */
+		if (flags & GPIO_V2_LINE_FLAG_EVENT_CLOCK_HARDWARE) {
+			ret = gpiod_req_hw_timestamp_ns(desc, process_hw_ts,
+							process_hw_ts_thread,
+							&lr->lines[i]);
+			if (ret)
+				return ret;
+		} else {
+			/*
+			 * HTE subsys will do nothing if there is nothing to
+			 * release.
+			 */
+			gpiod_rel_hw_timestamp_ns(desc);
+		}
+
 		blocking_notifier_call_chain(&desc->gdev->notifier,
 					     GPIO_V2_LINE_CHANGED_CONFIG,
 					     desc);
@@ -1409,6 +1542,14 @@ static int linereq_create(struct gpio_device *gdev, void __user *ip)
 					flags & GPIO_V2_LINE_EDGE_FLAGS);
 			if (ret)
 				goto out_free_linereq;
+
+			if (flags & GPIO_V2_LINE_FLAG_EVENT_CLOCK_HARDWARE) {
+				ret = gpiod_req_hw_timestamp_ns(desc, process_hw_ts,
+							process_hw_ts_thread,
+							&lr->lines[i]);
+				if (ret)
+					goto out_free_linereq;
+			}
 		}
 
 		blocking_notifier_call_chain(&desc->gdev->notifier,
@@ -1959,6 +2100,8 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc,
 
 	if (test_bit(FLAG_EVENT_CLOCK_REALTIME, &desc->flags))
 		info->flags |= GPIO_V2_LINE_FLAG_EVENT_CLOCK_REALTIME;
+	else if (test_bit(FLAG_EVENT_CLOCK_HARDWARE, &desc->flags))
+		info->flags |= GPIO_V2_LINE_FLAG_EVENT_CLOCK_HARDWARE;
 
 	debounce_period_us = READ_ONCE(desc->debounce_period_us);
 	if (debounce_period_us) {
diff --git a/include/uapi/linux/gpio.h b/include/uapi/linux/gpio.h
index eaaea3d8e6b4..d360545b4c21 100644
--- a/include/uapi/linux/gpio.h
+++ b/include/uapi/linux/gpio.h
@@ -80,6 +80,7 @@ enum gpio_v2_line_flag {
 	GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN	= _BITULL(9),
 	GPIO_V2_LINE_FLAG_BIAS_DISABLED		= _BITULL(10),
 	GPIO_V2_LINE_FLAG_EVENT_CLOCK_REALTIME	= _BITULL(11),
+	GPIO_V2_LINE_FLAG_EVENT_CLOCK_HARDWARE	= _BITULL(12),
 };
 
 /**
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [RFC v2 09/11] tools: gpio: Add new hardware clock type
  2021-09-30 23:26 [RFC v2 00/11] Intro to Hardware timestamping engine Dipen Patel
                   ` (7 preceding siblings ...)
  2021-09-30 23:26 ` [RFC v2 08/11] gpiolib: cdev: Add hardware timestamp clock type Dipen Patel
@ 2021-09-30 23:26 ` Dipen Patel
  2021-10-03 22:02   ` Linus Walleij
  2021-09-30 23:26 ` [RFC v2 10/11] hte: Add tegra GPIO HTE test driver Dipen Patel
  2021-09-30 23:26 ` [RFC v2 11/11] MAINTAINERS: Added HTE Subsystem Dipen Patel
  10 siblings, 1 reply; 33+ messages in thread
From: Dipen Patel @ 2021-09-30 23:26 UTC (permalink / raw)
  To: thierry.reding, jonathanh, linux-kernel, linux-tegra, linux-gpio,
	linus.walleij, bgolaszewski, warthog618, devicetree, linux-doc,
	robh+dt
  Cc: Dipen Patel

gpiolib-cdev is extended to support hardware clock type, this
patch reflects that fact.

Signed-off-by: Dipen Patel <dipenp@nvidia.com>
---
 tools/gpio/gpio-event-mon.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/tools/gpio/gpio-event-mon.c b/tools/gpio/gpio-event-mon.c
index a2b233fdb572..bed52333698d 100644
--- a/tools/gpio/gpio-event-mon.c
+++ b/tools/gpio/gpio-event-mon.c
@@ -149,6 +149,7 @@ void print_usage(void)
 		"  -r         Listen for rising edges\n"
 		"  -f         Listen for falling edges\n"
 		"  -w         Report the wall-clock time for events\n"
+		"  -t         Report the hardware timestamp for events\n"
 		"  -b <n>     Debounce the line with period n microseconds\n"
 		" [-c <n>]    Do <n> loops (optional, infinite loop if not stated)\n"
 		"  -?         This helptext\n"
@@ -174,7 +175,7 @@ int main(int argc, char **argv)
 
 	memset(&config, 0, sizeof(config));
 	config.flags = GPIO_V2_LINE_FLAG_INPUT;
-	while ((c = getopt(argc, argv, "c:n:o:b:dsrfw?")) != -1) {
+	while ((c = getopt(argc, argv, "c:n:o:b:dsrfwt?")) != -1) {
 		switch (c) {
 		case 'c':
 			loops = strtoul(optarg, NULL, 10);
@@ -208,6 +209,9 @@ int main(int argc, char **argv)
 		case 'w':
 			config.flags |= GPIO_V2_LINE_FLAG_EVENT_CLOCK_REALTIME;
 			break;
+		case 't':
+			config.flags |= GPIO_V2_LINE_FLAG_EVENT_CLOCK_HARDWARE;
+			break;
 		case '?':
 			print_usage();
 			return -1;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [RFC v2 10/11] hte: Add tegra GPIO HTE test driver
  2021-09-30 23:26 [RFC v2 00/11] Intro to Hardware timestamping engine Dipen Patel
                   ` (8 preceding siblings ...)
  2021-09-30 23:26 ` [RFC v2 09/11] tools: gpio: Add new hardware " Dipen Patel
@ 2021-09-30 23:26 ` Dipen Patel
  2021-10-01 23:47   ` Randy Dunlap
  2021-09-30 23:26 ` [RFC v2 11/11] MAINTAINERS: Added HTE Subsystem Dipen Patel
  10 siblings, 1 reply; 33+ messages in thread
From: Dipen Patel @ 2021-09-30 23:26 UTC (permalink / raw)
  To: thierry.reding, jonathanh, linux-kernel, linux-tegra, linux-gpio,
	linus.walleij, bgolaszewski, warthog618, devicetree, linux-doc,
	robh+dt
  Cc: Dipen Patel

Tegra194 GPIO controller and HTE supports AON GPIO lines for realtime
timestamp using hardware means. This in kernel gpio consumer test
driver demonstrates that functionality indirectly using HTE subsytem
through GPIOLIB framework. During probe it also registers sysfs
interface /sys/kernel/tegra_hte_gpio_test/gpio_en_dis. The value 1
enables gpio line for the HTE functionality while the value 0
disables that.

The test driver can be compiled as a module and takes optional
parameters gpio_out and gpio_in of type uint that specifies GPIO
numbers.

This patch also adds compilation support in Kconfig and Makefile.

Signed-off-by: Dipen Patel <dipenp@nvidia.com>
---
 drivers/hte/Kconfig                  |   9 +
 drivers/hte/Makefile                 |   1 +
 drivers/hte/hte-tegra194-gpio-test.c | 252 +++++++++++++++++++++++++++
 3 files changed, 262 insertions(+)
 create mode 100644 drivers/hte/hte-tegra194-gpio-test.c

diff --git a/drivers/hte/Kconfig b/drivers/hte/Kconfig
index eb339526f141..57c97034d187 100644
--- a/drivers/hte/Kconfig
+++ b/drivers/hte/Kconfig
@@ -38,4 +38,13 @@ config HTE_TEGRA194_IRQ_TEST
 	  The NVIDIA Tegra194 GTE IRQ test driver demonstrates HTE subsystem
 	  usage for the LIC IRQ hardware timestamp.
 
+config HTE_TEGRA194_GPIO_TEST
+        tristate "NVIDIA Tegra194 HTE GPIO Test"
+        depends on HTE_TEGRA194
+        help
+	  The NVIDIA Tegra194 GTE GPIO test driver demonstrates how to use HTE
+	  subsystem indirectly through gpiolib API calls for GPIO line for the
+	  hardware assisted timestamping.
+
 endif
+
diff --git a/drivers/hte/Makefile b/drivers/hte/Makefile
index 75b7932c2ffc..1d12f3a36709 100644
--- a/drivers/hte/Makefile
+++ b/drivers/hte/Makefile
@@ -1,4 +1,5 @@
 obj-$(CONFIG_HTE)		+= hte.o
 obj-$(CONFIG_HTE_TEGRA194)	+= hte-tegra194.o
 obj-$(CONFIG_HTE_TEGRA194_IRQ_TEST) += hte-tegra194-irq-test.o
+obj-$(CONFIG_HTE_TEGRA194_GPIO_TEST) += hte-tegra194-gpio-test.o
 
diff --git a/drivers/hte/hte-tegra194-gpio-test.c b/drivers/hte/hte-tegra194-gpio-test.c
new file mode 100644
index 000000000000..418f7df7b1b8
--- /dev/null
+++ b/drivers/hte/hte-tegra194-gpio-test.c
@@ -0,0 +1,252 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 NVIDIA Corporation
+ *
+ * Author: Dipen Patel <dipenp@nvidia.com>
+ */
+
+#include <linux/version.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/timer.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+
+/*
+ * Tegra194 On chip HTE (hardware timestamping engine) also known as GTE
+ * (generic timestamping engine) can monitor subset of GPIO lines for the event
+ * and timestamp accordingly.
+ *
+ * This sample HTE GPIO test driver demonstrates HTE API usage indirectly
+ * through GPIOLIB framework. It enables hardware timestamp on gpio_in line.
+ * Also the gpio_in is configured to be a rising edge interrupt.
+ *
+ * Note: gpio_out and gpio_in need to be shorted externally in order for this
+ * test driver to work for the GPIO monitoring. The test driver has been
+ * tested on Jetson AGX platform by shorting pin 32 and 16 on 40 pin header.
+ */
+
+static unsigned int gpio_in = 322;
+module_param(gpio_in, uint, 0660);
+
+static unsigned int gpio_out = 321;
+module_param(gpio_out, uint, 0660);
+
+static struct tegra_hte_test {
+	bool is_ts_en;
+	int gpio_in_irq;
+	struct gpio_desc *gpio_in;
+	struct gpio_desc *gpio_out;
+	struct timer_list timer;
+	struct kobject *kobj;
+} hte;
+
+static hte_return_t process_hw_ts(struct hte_ts_data *ts, void *p)
+{
+	char *edge;
+	(void)p;
+
+	if (!ts)
+		return HTE_CB_ERROR;
+
+	if (ts->dir >= HTE_DIR_NOSUPP)
+		edge = "rising";
+
+	pr_info("GPIO HW timestamp(%llu): %llu, edge: %s\n", ts->seq, ts->tsc,
+		(ts->dir < HTE_DIR_NOSUPP) ? ((ts->dir == HTE_FALLING_EDGE_TS) ?
+					      "falling" : "rising") : edge);
+
+	return HTE_CB_HANDLED;
+}
+
+/*
+ * Sysfs attribute to request/release HTE gpio line
+ */
+static ssize_t store_gpio_en_dis(struct kobject *kobj,
+				 struct kobj_attribute *attr,
+				 const char *buf, size_t count)
+{
+	int ret = count;
+	unsigned long val = 0;
+	(void)kobj;
+	(void)attr;
+
+	if (kstrtoul(buf, 10, &val) < 0) {
+		ret = -EINVAL;
+		goto error;
+	}
+
+	if (val == 1) {
+		if (hte.is_ts_en) {
+			ret = -EEXIST;
+			goto error;
+		}
+
+		ret = gpiod_req_hw_timestamp_ns(hte.gpio_in, process_hw_ts,
+						NULL, NULL);
+		if (ret)
+			goto error;
+
+		hte.is_ts_en = true;
+	} else if (val == 0) {
+		if (!hte.is_ts_en) {
+			ret = -EINVAL;
+			goto error;
+		}
+		ret = gpiod_rel_hw_timestamp_ns(hte.gpio_in);
+		if (ret)
+			goto error;
+
+		hte.is_ts_en = false;
+	}
+
+	ret = count;
+
+error:
+	return ret;
+}
+
+struct kobj_attribute gpio_en_dis_attr =
+		__ATTR(gpio_en_dis, 0220, NULL, store_gpio_en_dis);
+
+static struct attribute *attrs[] = {
+	&gpio_en_dis_attr.attr,
+	NULL,
+};
+
+static struct attribute_group tegra_hte_test_attr_group = {
+	.attrs = attrs,
+};
+
+static int tegra_hte_test_sysfs_create(void)
+{
+	int ret;
+
+	/* Creates /sys/kernel/tegra_hte_gpio_test */
+	hte.kobj = kobject_create_and_add("tegra_hte_gpio_test", kernel_kobj);
+	if (!hte.kobj)
+		return -ENOMEM;
+
+	ret = sysfs_create_group(hte.kobj, &tegra_hte_test_attr_group);
+	if (ret)
+		kobject_put(hte.kobj);
+	return ret;
+}
+
+static void gpio_timer_cb(struct timer_list *t)
+{
+	(void)t;
+
+	gpiod_set_value(hte.gpio_out, !gpiod_get_value(hte.gpio_out));
+	mod_timer(&hte.timer, jiffies + msecs_to_jiffies(8000));
+}
+
+static irqreturn_t tegra_hte_test_gpio_isr(int irq, void *data)
+{
+	(void)irq;
+	(void)data;
+
+	return IRQ_HANDLED;
+}
+
+static int __init tegra_hte_gpio_test_init(void)
+{
+	int ret = 0;
+
+	ret = gpio_request(gpio_out, "gte_test_gpio_out");
+	if (ret) {
+		pr_err("failed request gpio out\n");
+		return -EINVAL;
+	}
+
+	ret = gpio_request(gpio_in, "gte_test_gpio_in");
+	if (ret) {
+		pr_err("failed request gpio in\n");
+		ret = -EINVAL;
+		goto free_gpio_out;
+	}
+
+	hte.gpio_out = gpio_to_desc(gpio_out);
+	if (!hte.gpio_out) {
+		pr_err("failed convert gpio out to desc\n");
+		ret = -EINVAL;
+		goto free_gpio_in;
+	}
+
+	hte.gpio_in = gpio_to_desc(gpio_in);
+	if (!hte.gpio_in) {
+		pr_err("failed convert gpio in to desc\n");
+		ret = -EINVAL;
+		goto free_gpio_in;
+	}
+
+	ret = gpiod_direction_output(hte.gpio_out, 0);
+	if (ret) {
+		pr_err("failed to set output\n");
+		ret = -EINVAL;
+		goto free_gpio_in;
+	}
+
+	ret = gpiod_direction_input(hte.gpio_in);
+	if (ret) {
+		pr_err("failed to set input\n");
+		ret = -EINVAL;
+		goto free_gpio_in;
+	}
+
+	ret = gpiod_to_irq(hte.gpio_in);
+	if (ret < 0) {
+		pr_err("failed to map GPIO to IRQ: %d\n", ret);
+		ret = -ENXIO;
+		goto free_gpio_in;
+	}
+
+	hte.gpio_in_irq = ret;
+
+	ret = request_irq(ret, tegra_hte_test_gpio_isr,
+			  IRQF_TRIGGER_RISING,
+			  "tegra_hte_gpio_test_isr", &hte);
+	if (ret) {
+		pr_err("failed to acquire IRQ\n");
+		ret = -ENXIO;
+		goto free_irq;
+	}
+
+	ret = tegra_hte_test_sysfs_create();
+	if (ret != 0) {
+		pr_err("sysfs creation failed\n");
+		ret = -ENXIO;
+		goto free_irq;
+	}
+
+	timer_setup(&hte.timer, gpio_timer_cb, 0);
+	mod_timer(&hte.timer, jiffies + msecs_to_jiffies(5000));
+
+	return 0;
+
+free_irq:
+	free_irq(hte.gpio_in_irq, &hte);
+free_gpio_in:
+	gpio_free(gpio_in);
+free_gpio_out:
+	gpio_free(gpio_out);
+
+	return ret;
+}
+
+static void __exit tegra_hte_gpio_test_exit(void)
+{
+	free_irq(hte.gpio_in_irq, &hte);
+	gpio_free(gpio_in);
+	gpio_free(gpio_out);
+	kobject_put(hte.kobj);
+	del_timer(&hte.timer);
+}
+
+module_init(tegra_hte_gpio_test_init);
+module_exit(tegra_hte_gpio_test_exit);
+MODULE_AUTHOR("Dipen Patel <dipenp@nvidia.com>");
+MODULE_LICENSE("GPL v2");
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [RFC v2 11/11] MAINTAINERS: Added HTE Subsystem
  2021-09-30 23:26 [RFC v2 00/11] Intro to Hardware timestamping engine Dipen Patel
                   ` (9 preceding siblings ...)
  2021-09-30 23:26 ` [RFC v2 10/11] hte: Add tegra GPIO HTE test driver Dipen Patel
@ 2021-09-30 23:26 ` Dipen Patel
  2021-10-02  0:08   ` Randy Dunlap
  10 siblings, 1 reply; 33+ messages in thread
From: Dipen Patel @ 2021-09-30 23:26 UTC (permalink / raw)
  To: thierry.reding, jonathanh, linux-kernel, linux-tegra, linux-gpio,
	linus.walleij, bgolaszewski, warthog618, devicetree, linux-doc,
	robh+dt
  Cc: Dipen Patel

Added myself as a maintainer for this new Hardware Timestamping Engine
(HTE) subsystem.

Signed-off-by: Dipen Patel <dipenp@nvidia.com>
---
 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index abd0dd5aa003..03ae8056c35b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8659,6 +8659,14 @@ L:	linux-input@vger.kernel.org
 S:	Maintained
 F:	drivers/input/touchscreen/htcpen.c
 
+HTE SUBSYSTEM
+M:	dipenp@nvidia.com
+S:	Maintained
+F:	drivers/hte/*
+F:	include/linux/hte.h
+F:	Documentation/hte/*
+F:	Documentation/devicetree/bindings/hte/*
+
 HTS221 TEMPERATURE-HUMIDITY IIO DRIVER
 M:	Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
 L:	linux-iio@vger.kernel.org
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* Re: [RFC v2 06/11] gpiolib: Add HTE support
  2021-09-30 23:26 ` [RFC v2 06/11] gpiolib: Add HTE support Dipen Patel
@ 2021-10-01  9:19   ` kernel test robot
  2021-10-03 22:01   ` Linus Walleij
  1 sibling, 0 replies; 33+ messages in thread
From: kernel test robot @ 2021-10-01  9:19 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 15328 bytes --]

Hi Dipen,

[FYI, it's a private test report for your RFC patch.]
[auto build test ERROR on 2d02a18f75fc81177a4e30f3aaaed9af06cc3adc]

url:    https://github.com/0day-ci/linux/commits/Dipen-Patel/Intro-to-Hardware-timestamping-engine/20211001-072745
base:   2d02a18f75fc81177a4e30f3aaaed9af06cc3adc
config: ia64-defconfig (attached as .config)
compiler: ia64-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/bd7dcd8a026a55d05ae0b2dba5aaf5a926d9c7b6
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Dipen-Patel/Intro-to-Hardware-timestamping-engine/20211001-072745
        git checkout bd7dcd8a026a55d05ae0b2dba5aaf5a926d9c7b6
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=ia64 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from drivers/net/phy/mdio_bus.c:17:
>> include/linux/gpio/consumer.h:362:45: error: unknown type name 'hte_ts_threaded'; did you mean 'hte_ts_threaded_cb_t'?
     362 |                                             hte_ts_threaded tcb,
         |                                             ^~~~~~~~~~~~~~~
         |                                             hte_ts_threaded_cb_t
--
   In file included from include/linux/nvmem-provider.h:14,
                    from include/linux/rtc.h:18,
                    from include/linux/efi.h:20,
                    from drivers/firmware/efi/efi.c:22:
>> include/linux/gpio/consumer.h:362:45: error: unknown type name 'hte_ts_threaded'; did you mean 'hte_ts_threaded_cb_t'?
     362 |                                             hte_ts_threaded tcb,
         |                                             ^~~~~~~~~~~~~~~
         |                                             hte_ts_threaded_cb_t
   drivers/firmware/efi/efi.c:166:16: warning: no previous prototype for 'efi_attr_is_visible' [-Wmissing-prototypes]
     166 | umode_t __weak efi_attr_is_visible(struct kobject *kobj, struct attribute *attr,
         |                ^~~~~~~~~~~~~~~~~~~
--
   In file included from include/linux/nvmem-provider.h:14,
                    from include/linux/rtc.h:18,
                    from include/linux/efi.h:20,
                    from drivers/firmware/efi/sysfb_efi.c:18:
>> include/linux/gpio/consumer.h:362:45: error: unknown type name 'hte_ts_threaded'; did you mean 'hte_ts_threaded_cb_t'?
     362 |                                             hte_ts_threaded tcb,
         |                                             ^~~~~~~~~~~~~~~
         |                                             hte_ts_threaded_cb_t
   drivers/firmware/efi/sysfb_efi.c:72:6: warning: no previous prototype for 'efifb_setup_from_dmi' [-Wmissing-prototypes]
      72 | void efifb_setup_from_dmi(struct screen_info *si, const char *opt)
         |      ^~~~~~~~~~~~~~~~~~~~
--
   In file included from include/linux/nvmem-provider.h:14,
                    from include/linux/rtc.h:18,
                    from include/linux/efi.h:20,
                    from init/main.c:53:
>> include/linux/gpio/consumer.h:362:45: error: unknown type name 'hte_ts_threaded'; did you mean 'hte_ts_threaded_cb_t'?
     362 |                                             hte_ts_threaded tcb,
         |                                             ^~~~~~~~~~~~~~~
         |                                             hte_ts_threaded_cb_t
   init/main.c:790:20: warning: no previous prototype for 'mem_encrypt_init' [-Wmissing-prototypes]
     790 | void __init __weak mem_encrypt_init(void) { }
         |                    ^~~~~~~~~~~~~~~~
   init/main.c:792:20: warning: no previous prototype for 'poking_init' [-Wmissing-prototypes]
     792 | void __init __weak poking_init(void) { }
         |                    ^~~~~~~~~~~
--
   In file included from include/linux/nvmem-provider.h:14,
                    from include/linux/rtc.h:18,
                    from include/linux/efi.h:20,
                    from arch/ia64/kernel/efi.c:33:
>> include/linux/gpio/consumer.h:362:45: error: unknown type name 'hte_ts_threaded'; did you mean 'hte_ts_threaded_cb_t'?
     362 |                                             hte_ts_threaded tcb,
         |                                             ^~~~~~~~~~~~~~~
         |                                             hte_ts_threaded_cb_t
   arch/ia64/kernel/efi.c: In function 'efi_init':
   arch/ia64/kernel/efi.c:490:13: warning: variable 'efi_desc_size' set but not used [-Wunused-but-set-variable]
     490 |         u64 efi_desc_size;
         |             ^~~~~~~~~~~~~
   arch/ia64/kernel/efi.c:489:31: warning: variable 'efi_map_end' set but not used [-Wunused-but-set-variable]
     489 |         void *efi_map_start, *efi_map_end;
         |                               ^~~~~~~~~~~
   arch/ia64/kernel/efi.c: At top level:
   arch/ia64/kernel/efi.c:971:1: warning: no previous prototype for 'find_memmap_space' [-Wmissing-prototypes]
     971 | find_memmap_space (void)
         | ^~~~~~~~~~~~~~~~~
--
   In file included from include/linux/nvmem-provider.h:14,
                    from include/linux/rtc.h:18,
                    from include/linux/efi.h:20,
                    from arch/ia64/kernel/process.c:30:
>> include/linux/gpio/consumer.h:362:45: error: unknown type name 'hte_ts_threaded'; did you mean 'hte_ts_threaded_cb_t'?
     362 |                                             hte_ts_threaded tcb,
         |                                             ^~~~~~~~~~~~~~~
         |                                             hte_ts_threaded_cb_t
   arch/ia64/kernel/process.c:155:1: warning: no previous prototype for 'console_print' [-Wmissing-prototypes]
     155 | console_print(const char *s)
         | ^~~~~~~~~~~~~
   arch/ia64/kernel/process.c:161:1: warning: no previous prototype for 'do_notify_resume_user' [-Wmissing-prototypes]
     161 | do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall)
         | ^~~~~~~~~~~~~~~~~~~~~
   arch/ia64/kernel/process.c:400:17: warning: no previous prototype for 'ia64_clone' [-Wmissing-prototypes]
     400 | asmlinkage long ia64_clone(unsigned long clone_flags, unsigned long stack_start,
         |                 ^~~~~~~~~~
   arch/ia64/kernel/process.c:557:1: warning: no previous prototype for 'cpu_halt' [-Wmissing-prototypes]
     557 | cpu_halt (void)
         | ^~~~~~~~
--
   In file included from include/linux/nvmem-provider.h:14,
                    from include/linux/rtc.h:18,
                    from include/linux/efi.h:20,
                    from arch/ia64/include/asm/sal.h:41,
                    from arch/ia64/kernel/sal.c:19:
>> include/linux/gpio/consumer.h:362:45: error: unknown type name 'hte_ts_threaded'; did you mean 'hte_ts_threaded_cb_t'?
     362 |                                             hte_ts_threaded tcb,
         |                                             ^~~~~~~~~~~~~~~
         |                                             hte_ts_threaded_cb_t
   arch/ia64/kernel/sal.c:43:29: warning: cast between incompatible function types from 'long int (*)(void)' to 'struct ia64_sal_retval (*)(u64, ...)' {aka 'struct ia64_sal_retval (*)(long long unsigned int, ...)'} [-Wcast-function-type]
      43 | ia64_sal_handler ia64_sal = (ia64_sal_handler) default_handler;
         |                             ^
--
   In file included from include/linux/nvmem-provider.h:14,
                    from include/linux/rtc.h:18,
                    from include/linux/efi.h:20,
                    from arch/ia64/include/asm/sal.h:41,
                    from arch/ia64/kernel/salinfo.c:51:
>> include/linux/gpio/consumer.h:362:45: error: unknown type name 'hte_ts_threaded'; did you mean 'hte_ts_threaded_cb_t'?
     362 |                                             hte_ts_threaded tcb,
         |                                             ^~~~~~~~~~~~~~~
         |                                             hte_ts_threaded_cb_t
   arch/ia64/kernel/salinfo.c:212:1: warning: no previous prototype for 'salinfo_log_wakeup' [-Wmissing-prototypes]
     212 | salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe)
         | ^~~~~~~~~~~~~~~~~~
--
   In file included from include/linux/nvmem-provider.h:14,
                    from include/linux/rtc.h:18,
                    from include/linux/efi.h:20,
                    from arch/ia64/kernel/setup.c:49:
>> include/linux/gpio/consumer.h:362:45: error: unknown type name 'hte_ts_threaded'; did you mean 'hte_ts_threaded_cb_t'?
     362 |                                             hte_ts_threaded tcb,
         |                                             ^~~~~~~~~~~~~~~
         |                                             hte_ts_threaded_cb_t
   arch/ia64/kernel/setup.c:1074:1: warning: no previous prototype for 'check_bugs' [-Wmissing-prototypes]
    1074 | check_bugs (void)
         | ^~~~~~~~~~
--
   In file included from include/linux/nvmem-provider.h:14,
                    from include/linux/rtc.h:18,
                    from include/linux/efi.h:20,
                    from arch/ia64/kernel/time.c:22:
>> include/linux/gpio/consumer.h:362:45: error: unknown type name 'hte_ts_threaded'; did you mean 'hte_ts_threaded_cb_t'?
     362 |                                             hte_ts_threaded tcb,
         |                                             ^~~~~~~~~~~~~~~
         |                                             hte_ts_threaded_cb_t
   arch/ia64/kernel/time.c:259:6: warning: no previous prototype for 'ia64_init_itm' [-Wmissing-prototypes]
     259 | void ia64_init_itm(void)
         |      ^~~~~~~~~~~~~
   arch/ia64/kernel/time.c:396:1: warning: no previous prototype for 'time_init' [-Wmissing-prototypes]
     396 | time_init (void)
         | ^~~~~~~~~
--
   In file included from include/linux/nvmem-provider.h:14,
                    from include/linux/rtc.h:18,
                    from include/linux/efi.h:20,
                    from arch/ia64/include/asm/sal.h:41,
                    from arch/ia64/kernel/mca.c:98:
>> include/linux/gpio/consumer.h:362:45: error: unknown type name 'hte_ts_threaded'; did you mean 'hte_ts_threaded_cb_t'?
     362 |                                             hte_ts_threaded tcb,
         |                                             ^~~~~~~~~~~~~~~
         |                                             hte_ts_threaded_cb_t
   arch/ia64/kernel/mca.c: In function 'ia64_mca_printk':
   arch/ia64/kernel/mca.c:212:13: warning: variable 'printed_len' set but not used [-Wunused-but-set-variable]
     212 |         int printed_len;
         |             ^~~~~~~~~~~
   arch/ia64/kernel/mca.c: At top level:
   arch/ia64/kernel/mca.c:505:1: warning: no previous prototype for 'search_mca_table' [-Wmissing-prototypes]
     505 | search_mca_table (const struct mca_table_entry *first,
         | ^~~~~~~~~~~~~~~~
   arch/ia64/kernel/mca.c:608:1: warning: no previous prototype for 'ia64_mca_register_cpev' [-Wmissing-prototypes]
     608 | ia64_mca_register_cpev (int cpev)
         | ^~~~~~~~~~~~~~~~~~~~~~
   arch/ia64/kernel/mca.c:1285:1: warning: no previous prototype for 'ia64_mca_handler' [-Wmissing-prototypes]
    1285 | ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
         | ^~~~~~~~~~~~~~~~
..


vim +362 include/linux/gpio/consumer.h

   334	
   335	
   336	static inline int gpiod_get_direction(const struct gpio_desc *desc)
   337	{
   338		/* GPIO can never have been requested */
   339		WARN_ON(desc);
   340		return -ENOSYS;
   341	}
   342	static inline int gpiod_direction_input(struct gpio_desc *desc)
   343	{
   344		/* GPIO can never have been requested */
   345		WARN_ON(desc);
   346		return -ENOSYS;
   347	}
   348	static inline int gpiod_direction_output(struct gpio_desc *desc, int value)
   349	{
   350		/* GPIO can never have been requested */
   351		WARN_ON(desc);
   352		return -ENOSYS;
   353	}
   354	static inline int gpiod_direction_output_raw(struct gpio_desc *desc, int value)
   355	{
   356		/* GPIO can never have been requested */
   357		WARN_ON(desc);
   358		return -ENOSYS;
   359	}
   360	static inline int gpiod_req_hw_timestamp_ns(struct gpio_desc *desc,
   361						    hte_ts_cb_t cb,
 > 362						    hte_ts_threaded tcb,
   363						    void *data)
   364	{
   365		WARN_ON(desc);
   366		return -ENOSYS;
   367	}
   368	static inline int gpiod_rel_hw_timestamp_ns(struct gpio_desc *desc)
   369	{
   370		WARN_ON(desc);
   371		return -ENOSYS;
   372	}
   373	static inline int gpiod_get_value(const struct gpio_desc *desc)
   374	{
   375		/* GPIO can never have been requested */
   376		WARN_ON(desc);
   377		return 0;
   378	}
   379	static inline int gpiod_get_array_value(unsigned int array_size,
   380						struct gpio_desc **desc_array,
   381						struct gpio_array *array_info,
   382						unsigned long *value_bitmap)
   383	{
   384		/* GPIO can never have been requested */
   385		WARN_ON(desc_array);
   386		return 0;
   387	}
   388	static inline void gpiod_set_value(struct gpio_desc *desc, int value)
   389	{
   390		/* GPIO can never have been requested */
   391		WARN_ON(desc);
   392	}
   393	static inline int gpiod_set_array_value(unsigned int array_size,
   394						struct gpio_desc **desc_array,
   395						struct gpio_array *array_info,
   396						unsigned long *value_bitmap)
   397	{
   398		/* GPIO can never have been requested */
   399		WARN_ON(desc_array);
   400		return 0;
   401	}
   402	static inline int gpiod_get_raw_value(const struct gpio_desc *desc)
   403	{
   404		/* GPIO can never have been requested */
   405		WARN_ON(desc);
   406		return 0;
   407	}
   408	static inline int gpiod_get_raw_array_value(unsigned int array_size,
   409						    struct gpio_desc **desc_array,
   410						    struct gpio_array *array_info,
   411						    unsigned long *value_bitmap)
   412	{
   413		/* GPIO can never have been requested */
   414		WARN_ON(desc_array);
   415		return 0;
   416	}
   417	static inline void gpiod_set_raw_value(struct gpio_desc *desc, int value)
   418	{
   419		/* GPIO can never have been requested */
   420		WARN_ON(desc);
   421	}
   422	static inline int gpiod_set_raw_array_value(unsigned int array_size,
   423						    struct gpio_desc **desc_array,
   424						    struct gpio_array *array_info,
   425						    unsigned long *value_bitmap)
   426	{
   427		/* GPIO can never have been requested */
   428		WARN_ON(desc_array);
   429		return 0;
   430	}
   431	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 20045 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC v2 03/11] hte: Add tegra194 HTE kernel provider
  2021-09-30 23:26 ` [RFC v2 03/11] hte: Add tegra194 HTE kernel provider Dipen Patel
@ 2021-10-01 23:44   ` Randy Dunlap
  2021-10-02  0:07   ` Randy Dunlap
  1 sibling, 0 replies; 33+ messages in thread
From: Randy Dunlap @ 2021-10-01 23:44 UTC (permalink / raw)
  To: Dipen Patel, thierry.reding, jonathanh, linux-kernel,
	linux-tegra, linux-gpio, linus.walleij, bgolaszewski, warthog618,
	devicetree, linux-doc, robh+dt

On 9/30/21 4:26 PM, Dipen Patel wrote:
> +-----------
> +The Nvidia tegra194 HTE provider driver implements two GTE
> +(Generic Timestamping Engine) instances 1) GPIO GTE and 2) LIC IRQ GTE. The
> +both GTEs instances get the timestamp from the system counter TSC which has
> +31.25MHz clock rate, and the driver converts clock tick rate to nano seconds
> +before storing it as timestamp value.
> +
> +GPIO GTE
> +--------
> +
> +This GTE instance timestamps GPIO in real time, for that to happen GPIO
> +needs to be configured as input and IRQ needs to ba enabled. The only always on
> +(AON) gpio controller instance supports timestamping GPIOs in realtime and it

Here we have text that tells what AON means, but in the first paragraph above,
there is nothing that tells us what LIC means. Please add that.

-- 
~Randy

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC v2 10/11] hte: Add tegra GPIO HTE test driver
  2021-09-30 23:26 ` [RFC v2 10/11] hte: Add tegra GPIO HTE test driver Dipen Patel
@ 2021-10-01 23:47   ` Randy Dunlap
  2021-11-03  5:07     ` Dipen Patel
  0 siblings, 1 reply; 33+ messages in thread
From: Randy Dunlap @ 2021-10-01 23:47 UTC (permalink / raw)
  To: Dipen Patel, thierry.reding, jonathanh, linux-kernel,
	linux-tegra, linux-gpio, linus.walleij, bgolaszewski, warthog618,
	devicetree, linux-doc, robh+dt

Hi,

On 9/30/21 4:26 PM, Dipen Patel wrote:
> diff --git a/drivers/hte/Kconfig b/drivers/hte/Kconfig
> index eb339526f141..57c97034d187 100644
> --- a/drivers/hte/Kconfig
> +++ b/drivers/hte/Kconfig
> @@ -38,4 +38,13 @@ config HTE_TEGRA194_IRQ_TEST
>   	  The NVIDIA Tegra194 GTE IRQ test driver demonstrates HTE subsystem
>   	  usage for the LIC IRQ hardware timestamp.
>   
> +config HTE_TEGRA194_GPIO_TEST
> +        tristate "NVIDIA Tegra194 HTE GPIO Test"
> +        depends on HTE_TEGRA194
> +        help
> +	  The NVIDIA Tegra194 GTE GPIO test driver demonstrates how to use HTE

	                                                            to use the HTE

> +	  subsystem indirectly through gpiolib API calls for GPIO line for the

	                                                          lines

> +	  hardware assisted timestamping.

	  hardware-assisted

> +
>   endif

Also:

Please follow coding-style for Kconfig files:

(from Documentation/process/coding-style.rst, section 10):

For all of the Kconfig* configuration files throughout the source tree,
the indentation is somewhat different.  Lines under a ``config`` definition
are indented with one tab, while help text is indented an additional two
spaces.

Some of the lines above are indented with spaces instead of one tab.


thanks.
-- 
~Randy

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC v2 02/11] drivers: Add hardware timestamp engine (HTE)
  2021-09-30 23:26 ` [RFC v2 02/11] drivers: Add hardware timestamp engine (HTE) Dipen Patel
@ 2021-10-01 23:53   ` Randy Dunlap
  2021-11-03  0:37     ` Dipen Patel
  0 siblings, 1 reply; 33+ messages in thread
From: Randy Dunlap @ 2021-10-01 23:53 UTC (permalink / raw)
  To: Dipen Patel, thierry.reding, jonathanh, linux-kernel,
	linux-tegra, linux-gpio, linus.walleij, bgolaszewski, warthog618,
	devicetree, linux-doc, robh+dt

On 9/30/21 4:26 PM, Dipen Patel wrote:
> diff --git a/drivers/hte/Kconfig b/drivers/hte/Kconfig
> new file mode 100644
> index 000000000000..6fdf243d281b
> --- /dev/null
> +++ b/drivers/hte/Kconfig
> @@ -0,0 +1,22 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +menuconfig HTE
> +	bool "Hardware Timestamping Engine (HTE) Support"
> +	help
> +	  Hardware Timestamping Engine (HTE) Support.
> +
> +	  Some devices provide hardware timestamping engine which can timestamp

	               provide a hardware

> +	  certain device lines/signals in realtime. This way to provide

	                                            This provides a

> +	  hardware assisted timestamp to generic signals like GPIOs, IRQs lines

	  hardware-assisted                              like GPIOs or IRQ lines.


> +	  comes with benefit for the applications like autonomous machines

	  It comes with a benefit for applications like

> +	  needing accurate timestamping event with less jitter.
> +
> +	  This framework provides a generic interface to such HTE devices
> +	  within the Linux kernel. It provides an API to register and
> +	  unregister a HTE provider chip, configurable sw buffer to

	                                               software

> +	  store the timestamps, push the timestamp from the HTE providers and
> +	  retrieve timestamps for the consumers. It also provides means for the
> +	  consumers to request signals it wishes to hardware timestamp and
> +	  release them if not required.
> +
> +	  If unsure, say no.


HTH.
-- 
~Randy

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC v2 03/11] hte: Add tegra194 HTE kernel provider
  2021-09-30 23:26 ` [RFC v2 03/11] hte: Add tegra194 HTE kernel provider Dipen Patel
  2021-10-01 23:44   ` Randy Dunlap
@ 2021-10-02  0:07   ` Randy Dunlap
  2021-11-03  1:15     ` Dipen Patel
  1 sibling, 1 reply; 33+ messages in thread
From: Randy Dunlap @ 2021-10-02  0:07 UTC (permalink / raw)
  To: Dipen Patel, thierry.reding, jonathanh, linux-kernel,
	linux-tegra, linux-gpio, linus.walleij, bgolaszewski, warthog618,
	devicetree, linux-doc, robh+dt

On 9/30/21 4:26 PM, Dipen Patel wrote:
> diff --git a/Documentation/hte/tegra194-hte.rst b/Documentation/hte/tegra194-hte.rst
> new file mode 100644
> index 000000000000..fb229bda2408
> --- /dev/null
> +++ b/Documentation/hte/tegra194-hte.rst
> @@ -0,0 +1,56 @@
> +HTE Kernel provider driver
> +==========================
> +
> +Description
> +-----------
> +The Nvidia tegra194 HTE provider driver implements two GTE
> +(Generic Timestamping Engine) instances 1) GPIO GTE and 2) LIC IRQ GTE. The

                                  instances:                                ^^Drop "The"

> +both GTEs instances get the timestamp from the system counter TSC which has

    Both

> +31.25MHz clock rate, and the driver converts clock tick rate to nano seconds

                                                                    nanoseconds

> +before storing it as timestamp value.
> +
> +GPIO GTE
> +--------
> +
> +This GTE instance timestamps GPIO in real time, for that to happen GPIO

                                              time. For

> +needs to be configured as input and IRQ needs to ba enabled. The only always on

                                                     be

> +(AON) gpio controller instance supports timestamping GPIOs in realtime and it

          GPIO                                                    real time {or change
                            the instance 3 lines above to be "realtime"}

> +has 39 GPIO lines. The GPIO GTE and AON GPIO controller are tightly coupled as
> +it requires very specific bits to be set in GPIO config register before GPIO> +GTE can be used. The GPIO GTE functionality is accessed from the GPIOLIB
> +framework for the in kernel and userspace consumers. In the later case,

                      in-kernel                                 latter

> +requests go through GPIOLIB CDEV framework. The below APIs are added in GPIOLIB
> +framework to access HTE subsystem and GPIO GTE.
> +
> +.. kernel-doc:: drivers/gpio/gpiolib.c
> +   :functions: gpiod_req_hw_timestamp_ns gpiod_rel_hw_timestamp_ns
> +
> +There is hte-tegra194-gpio-test.c, located in ``drivers/hte/`` directory, test
> +driver which demonstrates above APIs for the Jetson AGX platform.
> +
> +For userspace consumers, GPIO_V2_LINE_FLAG_EVENT_CLOCK_HARDWARE flag must be
> +specifed during IOCTL calls, refer ``tools/gpio/gpio-event-mon.c``, which

    specified             calls. Refer to

> +returns the timestamp in nano second.

                             nanoseconds.

> +
> +LIC IRQ GTE
> +-----------
> +
> +This GTE instance timestamp LIC IRQ lines in real time. There are 352 IRQ

                      timestamps                 ^^^^^^^^^ {be consistent}
   (also (repeating a prior email) define "LIC")

> +lines which this instance can help timestamp realtime. The hte devicetree

                              can add timestamps to in realtime.

> +binding described at ``Documentation/devicetree/bindings/hte/`` gives out

                                                                    provides an

> +example how consumer can request IRQ line, since it is one to one mapping,

    example of how a consumer can request an IRQ line. Since it is a one-to-one mapping,

> +consumers can simply specify IRQ number that they are interested in. There is

                         specify the IRQ number

> +no userspace consumer support for this GTE instance. The sample test code
> +hte-tegra194-irq-test.c, located in ``drivers/hte/`` directory,

                                     in the

> +demonstrates how to use IRQ GTE instance. The below is sample device tree

                 how to use an IRQ GTE instance.

> +snippet code for the test driver::
> +
> + tegra_hte_irq_test {
> +        compatible = "nvidia,tegra194-hte-irq-test";
> +        htes = <&tegra_hte_lic 0x19>;
> +        hte-names = "hte-lic";
> + };
> +
> +The provider source code of both IRQ and GPIO GTE instances is locate at

                                                                   located

> +``drivers/hte/hte-tegra194.c``.
> +


-- 
~Randy

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC v2 11/11] MAINTAINERS: Added HTE Subsystem
  2021-09-30 23:26 ` [RFC v2 11/11] MAINTAINERS: Added HTE Subsystem Dipen Patel
@ 2021-10-02  0:08   ` Randy Dunlap
  2021-10-02  4:00     ` Joe Perches
  0 siblings, 1 reply; 33+ messages in thread
From: Randy Dunlap @ 2021-10-02  0:08 UTC (permalink / raw)
  To: Dipen Patel, thierry.reding, jonathanh, linux-kernel,
	linux-tegra, linux-gpio, linus.walleij, bgolaszewski, warthog618,
	devicetree, linux-doc, robh+dt

On 9/30/21 4:26 PM, Dipen Patel wrote:
> Added myself as a maintainer for this new Hardware Timestamping Engine
> (HTE) subsystem.
> 
> Signed-off-by: Dipen Patel <dipenp@nvidia.com>
> ---
>   MAINTAINERS | 8 ++++++++
>   1 file changed, 8 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index abd0dd5aa003..03ae8056c35b 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -8659,6 +8659,14 @@ L:	linux-input@vger.kernel.org
>   S:	Maintained
>   F:	drivers/input/touchscreen/htcpen.c
>   
> +HTE SUBSYSTEM
> +M:	dipenp@nvidia.com

Please update as documented:
	M: *Mail* patches to: FullName <address@domain>


> +S:	Maintained
> +F:	drivers/hte/*
> +F:	include/linux/hte.h
> +F:	Documentation/hte/*
> +F:	Documentation/devicetree/bindings/hte/*
> +
>   HTS221 TEMPERATURE-HUMIDITY IIO DRIVER
>   M:	Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
>   L:	linux-iio@vger.kernel.org
> 


-- 
~Randy

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC v2 01/11] Documentation: Add HTE subsystem guide
  2021-09-30 23:26 ` [RFC v2 01/11] Documentation: Add HTE subsystem guide Dipen Patel
@ 2021-10-02  0:18   ` Randy Dunlap
  2021-11-03  0:36     ` Dipen Patel
  0 siblings, 1 reply; 33+ messages in thread
From: Randy Dunlap @ 2021-10-02  0:18 UTC (permalink / raw)
  To: Dipen Patel, thierry.reding, jonathanh, linux-kernel,
	linux-tegra, linux-gpio, linus.walleij, bgolaszewski, warthog618,
	devicetree, linux-doc, robh+dt

On 9/30/21 4:26 PM, Dipen Patel wrote:
> Adding hte document which can help understand various APIs implemented
> in HTE framework for the HTE producers and the consumers.
> 
> Signed-off-by: Dipen Patel <dipenp@nvidia.com>
> ---
> Changes in v2:
> - Removed explanation, instead added kernel-doc references.
> 
>   Documentation/hte/hte.rst | 83 +++++++++++++++++++++++++++++++++++++++
>   1 file changed, 83 insertions(+)
>   create mode 100644 Documentation/hte/hte.rst
> 
> diff --git a/Documentation/hte/hte.rst b/Documentation/hte/hte.rst
> new file mode 100644
> index 000000000000..c9b1badae601
> --- /dev/null
> +++ b/Documentation/hte/hte.rst
> @@ -0,0 +1,83 @@
> +============================================
> +The Linux Hardware Timestamping Engine (HTE)
> +============================================
> +
> +:Author: Dipen Patel
> +
> +Introduction
> +------------
> +
> +Certain devices have built in hardware timestamping engines which can
> +monitor sets of system signals, lines, buses etc... in realtime for state
> +change; upon detecting the change they can automatically store the timestamp at
> +the moment of occurrence. Such functionality may help achieve better accuracy
> +in obtaining timestamp than using software counterparts i.e. ktime and friends.

                 timestamps

> +
> +This document describes the API that can be used by hardware timestamping
> +engine provider and consumer drivers that want to use the hardware timestamping
> +engine (HTE) framework. Both consumers and providers must
> +#include <linux/hte.h>.
> +
> +The HTE framework APIs for the providers
> +----------------------------------------
> +
> +.. kernel-doc:: drivers/hte/hte.c
> +   :functions: devm_hte_register_chip hte_push_ts_ns
> +
> +The HTE framework APIs for the consumers
> +----------------------------------------
> +
> +.. kernel-doc:: drivers/hte/hte.c
> +   :functions: devm_of_hte_request_ts hte_req_ts_by_hte_name hte_release_ts hte_enable_ts hte_disable_ts hte_get_clk_src_info
> +
> +The HTE framework public structures
> +-----------------------------------
> +.. kernel-doc:: include/linux/hte.h
> +
> +
> +More on the HTE timestamp data
> +------------------------------
> +The struct hte_ts_data is used to pass timestamp details between the consumers
> +and the providers. It expresses timestamp data in nano second in u64 data

                                                      nanosesconds
                                              possibly:           in a __u64 data

> +type. For now all the HTE APIs using struct hte_ts_data requires tsc to be in

                                                            require tsc to be in

> +nano seconds. An example of the typical hte_ts_data data life cycle, for the

    nanoseconds.

> +GPIO line is as follows::
> +
> + - Monitors GPIO line change.
> + - Detects the state change on GPIO line.
> + - Converts timestamps in nano seconds and stores it in tsc.

                              nanoseconds

> + - Stores GPIO direction in dir variable if the provider has that hardware
> + capability.
> + - Pushes this hte_ts_data object to HTE subsystem.
> + - HTE subsystem increments seq counter and invokes consumer provided callback.
> + Based on callback return value, the HTE starts kernel thread and invokes

                                             starts a kernel thread

> + secondary callback in the thread context.
> +
> +HTE subsystem debugfs attributes
> +--------------------------------
> +HTE subsystem creates debugfs attributes at ``/sys/kernel/debug/hte/``.
> +It also creates line/signal related debugfs attributes at

                         signal-related

> +``/sys/kernel/debug/hte/<provider>/<label or line id>/``.
> +
> +`ts_requested`
> +		The total number of entities requested from the given provider,
> +		where entity is the provider specific and could represent

		             is specified by the provider and could
(just guessing here; I could not parse it.)

> +		lines, GPIO, chip signals, buses etc...
> +                The attribute will be availble at

		                         available

> +		``/sys/kernel/debug/hte/<provider>/``.
> +
> +		Read only value

		Read-only value

> +
> +`total_ts`
> +		The total number of entities supported by the provider.
> +                The attribute will be availble at

		                         available

> +		``/sys/kernel/debug/hte/<provider>/``.
> +
> +		Read only value

		Read-only value

> +
> +`dropped_timestamps`
> +		The dropped timestamps for a given line.
> +                The attribute will be availble at

		                         available

> +		``/sys/kernel/debug/hte/<provider>/<label or line id>/``.
> +
> +		Read only value

		Read-only value
> 


-- 
~Randy

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC v2 11/11] MAINTAINERS: Added HTE Subsystem
  2021-10-02  0:08   ` Randy Dunlap
@ 2021-10-02  4:00     ` Joe Perches
  0 siblings, 0 replies; 33+ messages in thread
From: Joe Perches @ 2021-10-02  4:00 UTC (permalink / raw)
  To: Randy Dunlap, Dipen Patel, thierry.reding, jonathanh,
	linux-kernel, linux-tegra, linux-gpio, linus.walleij,
	bgolaszewski, warthog618, devicetree, linux-doc, robh+dt

On Fri, 2021-10-01 at 17:08 -0700, Randy Dunlap wrote:
> On 9/30/21 4:26 PM, Dipen Patel wrote:
> > Added myself as a maintainer for this new Hardware Timestamping Engine
> > (HTE) subsystem.
[]
> > diff --git a/MAINTAINERS b/MAINTAINERS
[]
> > +S:	Maintained
> > +F:	drivers/hte/*
> > +F:	include/linux/hte.h
> > +F:	Documentation/hte/*
> > +F:	Documentation/devicetree/bindings/hte/*

And using * does not support any possible subdirectory

Likely these should be:

F:	drivers/hte/
F:	include/linux/hte.h
F:	Documentation/hte/
F:	Documentation/devicetree/bindings/hte/



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC v2 04/11] dt-bindings: Add HTE bindings
  2021-09-30 23:26 ` [RFC v2 04/11] dt-bindings: Add HTE bindings Dipen Patel
@ 2021-10-03 21:53   ` Linus Walleij
  2021-10-08 22:11   ` Rob Herring
  1 sibling, 0 replies; 33+ messages in thread
From: Linus Walleij @ 2021-10-03 21:53 UTC (permalink / raw)
  To: Dipen Patel
  Cc: thierry.reding, Jon Hunter, linux-kernel, linux-tegra,
	open list:GPIO SUBSYSTEM, Bartosz Golaszewski, Kent Gibson,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux Doc Mailing List, Rob Herring

On Fri, Oct 1, 2021 at 1:26 AM Dipen Patel <dipenp@nvidia.com> wrote:

> Introduces HTE devicetree binding details for the HTE subsystem. It
> includes examples for the consumers, binding details for the providers
> and specific binding details for the Tegra194 based HTE providers.
>
> Signed-off-by: Dipen Patel <dipenp@nvidia.com>
> ---
> Changes in v2:
> - Replace hte with hardware-timestamp for property names
> - Renamed file
> - Removed example from the common dt binding file.

This looks good to me!
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC v2 08/11] gpiolib: cdev: Add hardware timestamp clock type
  2021-09-30 23:26 ` [RFC v2 08/11] gpiolib: cdev: Add hardware timestamp clock type Dipen Patel
@ 2021-10-03 21:59   ` Linus Walleij
  2021-10-03 22:09   ` Linus Walleij
  1 sibling, 0 replies; 33+ messages in thread
From: Linus Walleij @ 2021-10-03 21:59 UTC (permalink / raw)
  To: Dipen Patel
  Cc: thierry.reding, Jon Hunter, linux-kernel, linux-tegra,
	open list:GPIO SUBSYSTEM, Bartosz Golaszewski, Kent Gibson,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux Doc Mailing List, Rob Herring

On Fri, Oct 1, 2021 at 1:26 AM Dipen Patel <dipenp@nvidia.com> wrote:

> This patch adds new clock type for the GPIO controller which can
> timestamp gpio lines in realtime using hardware means. To expose such
> functionalities to the userspace, code has been added in this patch
> where during line create call, it checks for new clock type and if
> requested, calls hardware timestamp related API from gpiolib.c.
> During line change event, the HTE subsystem pushes timestamp data
> through callbacks.
>
> Signed-off-by: Dipen Patel <dipenp@nvidia.com>
> ---
> Changes in v2:
> - Added hte_dir and static structure hte_ts_desc.
> - Added callbacks which get invoked by HTE when new data is available.
> - Better use of hte_dir and seq from hte_ts_desc.
> - Modified sw debounce function to accommodate hardware timestamping.

This looks pretty much like I imagined it would, good work!
I am a bit busy now and unable to do an in-depth review
(brain parse the code and make sure all is sane) but it looks
really good, so at least I can say:
Acked-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC v2 06/11] gpiolib: Add HTE support
  2021-09-30 23:26 ` [RFC v2 06/11] gpiolib: Add HTE support Dipen Patel
  2021-10-01  9:19   ` kernel test robot
@ 2021-10-03 22:01   ` Linus Walleij
  1 sibling, 0 replies; 33+ messages in thread
From: Linus Walleij @ 2021-10-03 22:01 UTC (permalink / raw)
  To: Dipen Patel
  Cc: thierry.reding, Jon Hunter, linux-kernel, linux-tegra,
	open list:GPIO SUBSYSTEM, Bartosz Golaszewski, Kent Gibson,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux Doc Mailing List, Rob Herring

On Fri, Oct 1, 2021 at 1:26 AM Dipen Patel <dipenp@nvidia.com> wrote:

> Some GPIO chip can provide hardware timestamp support on its GPIO lines
> , in order to support that additional API needs to be added which
> can talk to both GPIO chip and HTE (hardware timestamping engine)
> subsystem. This patch introduces APIs which gpio consumer can use
> to request hardware assisted timestamping. Below is the list of the APIs
> that are added in gpiolib subsystem.
>
> - gpiod_req_hw_timestamp_ns - Request HTE on specified GPIO line.
> - gpiod_rel_hw_timestamp_ns - Release HTE functionality on GPIO line.
>
> Signed-off-by: Dipen Patel <dipenp@nvidia.com>
> ---
> Changes in v2:
> - removed get timestamp and is timestamp enabled APIs

Pretty straight forward IMO
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC v2 09/11] tools: gpio: Add new hardware clock type
  2021-09-30 23:26 ` [RFC v2 09/11] tools: gpio: Add new hardware " Dipen Patel
@ 2021-10-03 22:02   ` Linus Walleij
  0 siblings, 0 replies; 33+ messages in thread
From: Linus Walleij @ 2021-10-03 22:02 UTC (permalink / raw)
  To: Dipen Patel
  Cc: thierry.reding, Jon Hunter, linux-kernel, linux-tegra,
	open list:GPIO SUBSYSTEM, Bartosz Golaszewski, Kent Gibson,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux Doc Mailing List, Rob Herring

On Fri, Oct 1, 2021 at 1:26 AM Dipen Patel <dipenp@nvidia.com> wrote:

> gpiolib-cdev is extended to support hardware clock type, this
> patch reflects that fact.
>
> Signed-off-by: Dipen Patel <dipenp@nvidia.com>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC v2 08/11] gpiolib: cdev: Add hardware timestamp clock type
  2021-09-30 23:26 ` [RFC v2 08/11] gpiolib: cdev: Add hardware timestamp clock type Dipen Patel
  2021-10-03 21:59   ` Linus Walleij
@ 2021-10-03 22:09   ` Linus Walleij
  1 sibling, 0 replies; 33+ messages in thread
From: Linus Walleij @ 2021-10-03 22:09 UTC (permalink / raw)
  To: Dipen Patel
  Cc: thierry.reding, Jon Hunter, linux-kernel, linux-tegra,
	open list:GPIO SUBSYSTEM, Bartosz Golaszewski, Kent Gibson,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux Doc Mailing List, Rob Herring

On Fri, Oct 1, 2021 at 1:26 AM Dipen Patel <dipenp@nvidia.com> wrote:

> +       if (test_bit(FLAG_EVENT_CLOCK_HARDWARE, &line->desc->flags)) {

I don't know if it's here or a few other places as well we could sneak
in a IS_ENABLED(CONFIG_HTE) to make sure the compiler will
optimize out a bunch of the HTE support code if HTE is not in use?

Just an idea, I guess it's not the most urgent.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC v2 04/11] dt-bindings: Add HTE bindings
  2021-09-30 23:26 ` [RFC v2 04/11] dt-bindings: Add HTE bindings Dipen Patel
  2021-10-03 21:53   ` Linus Walleij
@ 2021-10-08 22:11   ` Rob Herring
  2021-11-03 21:43     ` Dipen Patel
  1 sibling, 1 reply; 33+ messages in thread
From: Rob Herring @ 2021-10-08 22:11 UTC (permalink / raw)
  To: Dipen Patel
  Cc: thierry.reding, jonathanh, linux-kernel, linux-tegra, linux-gpio,
	linus.walleij, bgolaszewski, warthog618, devicetree, linux-doc

On Thu, Sep 30, 2021 at 04:26:10PM -0700, Dipen Patel wrote:
> Introduces HTE devicetree binding details for the HTE subsystem. It
> includes examples for the consumers, binding details for the providers
> and specific binding details for the Tegra194 based HTE providers.
> 

This pattern of binding isn't easily checked completely by schema. You 
need a dtc check added too. Should be a 2 line change. (And dtc changes 
go upstream first).

> Signed-off-by: Dipen Patel <dipenp@nvidia.com>
> ---
> Changes in v2:
> - Replace hte with hardware-timestamp for property names
> - Renamed file
> - Removed example from the common dt binding file.
> 
>  .../hte/hardware-timestamps-common.yaml       | 29 +++++++
>  .../devicetree/bindings/hte/hte-consumer.yaml | 48 +++++++++++
>  .../bindings/hte/nvidia,tegra194-hte.yaml     | 79 +++++++++++++++++++
>  3 files changed, 156 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/hte/hardware-timestamps-common.yaml
>  create mode 100644 Documentation/devicetree/bindings/hte/hte-consumer.yaml
>  create mode 100644 Documentation/devicetree/bindings/hte/nvidia,tegra194-hte.yaml
> 
> diff --git a/Documentation/devicetree/bindings/hte/hardware-timestamps-common.yaml b/Documentation/devicetree/bindings/hte/hardware-timestamps-common.yaml
> new file mode 100644
> index 000000000000..8b8db3bc4dcf
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/hte/hardware-timestamps-common.yaml
> @@ -0,0 +1,29 @@
> +# SPDX-License-Identifier: GPL-2.0

Dual license new bindings.

> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/hte/hardware-timestamps-common.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Hardware timestamp providers
> +
> +maintainers:
> +  - Dipen Patel <dipenp@nvidia.com>
> +
> +description: |
> +  Some devices/SoCs have hardware time stamping engines which can use hardware
> +  means to timestamp entity in realtime. The entity could be anything from
> +  GPIOs, IRQs, Bus and so on. The hardware timestamp engine (HTE) present
> +  itself as a provider with the bindings described in this document.
> +
> +properties:
> +  $nodename:
> +    pattern: "^hardware-timestamps(@.*|-[0-9a-f])*$"

"^hardware-timestamp(@.*|-[0-9a-f])?$"

> +
> +  "#hardware-timestamps-cells":

Double plural:

#hardware-timestamp-cells

Arguably, the same string everywhere would have been an easier design, 
but let's keep consistency with (most) other flavors of this pattern.

> +    description:
> +      Number of cells in a HTE specifier.
> +
> +required:
> +  - "#hardware-timestamps-cells"
> +
> +additionalProperties: true
> diff --git a/Documentation/devicetree/bindings/hte/hte-consumer.yaml b/Documentation/devicetree/bindings/hte/hte-consumer.yaml
> new file mode 100644
> index 000000000000..cf65d1d44a18
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/hte/hte-consumer.yaml
> @@ -0,0 +1,48 @@
> +# SPDX-License-Identifier: GPL-2.0
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/hte/hte-consumer.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: HTE Consumer Device Tree Bindings
> +
> +maintainers:
> +  - Dipen Patel <dipenp@nvidia.com>
> +
> +description: |
> +  HTE properties should be named "hardware-timestamps". The exact meaning of
> +  each hardware-timestamps property must be documented in the device tree
> +  binding for each device. An optional property "hardware-timestamps-names" may
> +  contain a list of strings to label each of the HTE devices listed in the
> +  "hardware-timestamps" property.
> +
> +  The "hardware-timestamps-names" property if specified is used to map the name
> +  of the HTE device requested by the devm_of_hte_request_ts() or of_hte_request_ts
> +  call to an index into the list given by the "hardware-timestamps" property.
> +
> +properties:
> +  hardware-timestamps:
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    description:
> +      The list of HTE provider phandle. The provider must document the number
> +      of cell that must be passed in this property along with phandle.
> +
> +  hardware-timestamps-names:

hardware-timestamp-names


> +    $ref: /schemas/types.yaml#/definitions/string-array
> +    description:
> +      An optional string property.
> +
> +required:
> +  - "hardware-timestamps"

Don't need quotes.

> +
> +dependencies:
> +  hardware-timestamps-names: [ hardware-timestamps ]
> +
> +additionalProperties: true
> +
> +examples:
> +  - |
> +    hte_irq_consumer {
> +              hardware-timestamps = <&tegra_hte_lic 0x19>;
> +              hardware-timestamps-names = "hte-irq";
> +    };
> diff --git a/Documentation/devicetree/bindings/hte/nvidia,tegra194-hte.yaml b/Documentation/devicetree/bindings/hte/nvidia,tegra194-hte.yaml
> new file mode 100644
> index 000000000000..529926118f35
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/hte/nvidia,tegra194-hte.yaml
> @@ -0,0 +1,79 @@
> +# SPDX-License-Identifier: GPL-2.0
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/hte/nvidia,tegra194-hte.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Tegra194 on chip generic hardware timestamping engine (HTE)
> +
> +maintainers:
> +  - Dipen Patel <dipenp@nvidia.com>
> +
> +description: |
> +  Tegra194 SoC has multiple generic hardware timestamping engines which can
> +  monitor subset of GPIO and on chip IRQ lines for the state change, upon
> +  detection it will record timestamp (taken from system counter) in its
> +  internal hardware FIFO. It has bitmap array arranged in 32bit slices where

has a bitmap

> +  each bit represent signal/line to enable or disable for the hardware
> +  timestamping.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - nvidia,tegra194-gte-aon
> +      - nvidia,tegra194-gte-lic
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  int-threshold:

nvidia,int-threshold unless this is common for all hw timestamps?

> +    description:
> +      HTE device generates its interrupt based on this u32 FIFO threshold
> +      value. The recommended value is 1.
> +    minimum: 1
> +    maximum: 256
> +
> +  slices:

nvidia,slices

Needs a type.

> +    description:
> +      HTE lines are arranged in 32 bit slice where each bit represents different
> +      line/signal that it can enable/configure for the timestamp. It is u32
> +      property and depends on the HTE instance in the chip.
> +    enum: [3, 11]
> +
> +  '#hardware-timestamps-cells':
> +    const: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - slices
> +  - "#hardware-timestamps-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    tegra_hte_aon: hardware-timestamps@c1e0000 {
> +              compatible = "nvidia,tegra194-gte-aon";
> +              reg = <0xc1e0000 0x10000>;
> +              interrupts = <0 13 0x4>;
> +              int-threshold = <1>;
> +              slices = <3>;
> +              #hardware-timestamps-cells = <1>;
> +    };
> +
> +  - |
> +    tegra_hte_lic: hardware-timestamps@3aa0000 {
> +              compatible = "nvidia,tegra194-gte-lic";
> +              reg = <0x3aa0000 0x10000>;
> +              interrupts = <0 11 0x4>;
> +              int-threshold = <1>;
> +              slices = <11>;
> +              #hardware-timestamps-cells = <1>;
> +    };
> +
> +...
> -- 
> 2.17.1
> 
> 

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC v2 07/11] gpio: tegra186: Add HTE in gpio-tegra186 driver
  2021-09-30 23:26 ` [RFC v2 07/11] gpio: tegra186: Add HTE in gpio-tegra186 driver Dipen Patel
@ 2021-10-08 22:16   ` Rob Herring
  2021-11-03  5:05     ` Dipen Patel
  0 siblings, 1 reply; 33+ messages in thread
From: Rob Herring @ 2021-10-08 22:16 UTC (permalink / raw)
  To: Dipen Patel
  Cc: thierry.reding, jonathanh, linux-kernel, linux-tegra, linux-gpio,
	linus.walleij, bgolaszewski, warthog618, devicetree, linux-doc

On Thu, Sep 30, 2021 at 04:26:13PM -0700, Dipen Patel wrote:
> Tegra194 AON GPIO controller with the use of its internal hardware
> timestamping engine (HTE) also known as GTE can timestamp GPIO
> lines through system counter. This patch implements two callbacks
> which are essential for the gpio consumers that want such HTE
> functionality. The callbacks details can be found at
> include/gpio/driver.h.
> 
> Since AON GPIO controller depends on HTE engine, it creates hardware
> dependency between controller and AON HTE provider. To express that,
> the optional devicetree property is introduced for AON GPIO controller.
> 
> Signed-off-by: Dipen Patel <dipenp@nvidia.com>
> ---
>  .../bindings/gpio/nvidia,tegra186-gpio.txt    |  7 ++

Bindings should be a separate patch. Consider converting this to schema 
first too.

>  drivers/gpio/gpio-tegra186.c                  | 89 +++++++++++++++++++
>  2 files changed, 96 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/gpio/nvidia,tegra186-gpio.txt b/Documentation/devicetree/bindings/gpio/nvidia,tegra186-gpio.txt
> index adff16c71d21..00a3e47ab560 100644
> --- a/Documentation/devicetree/bindings/gpio/nvidia,tegra186-gpio.txt
> +++ b/Documentation/devicetree/bindings/gpio/nvidia,tegra186-gpio.txt
> @@ -127,6 +127,12 @@ Required properties:
>              - 8: Active low level-sensitive.
>              Valid combinations are 1, 2, 3, 4, 8.
>  
> +Optional properties:
> +- timestamp-engine

Should be in the common binding.

But then when do you use hardware-timestamps? This property seems to 
assume GPIO hand the timestamp engine have the same numbering of 
signals. I think you need to be able to map GPIOx to timestamp y. If you 
want a short cut for a 1-1 case, then that's another discussion.

> +    AON GPIO controller has timestamp engine which can hardware timestamp
> +    GPIO configured as input and IRQ. This property specifies hardware
> +    timestamp engine (HTE) device-tree node.
> +
>  Example:
>  
>  #include <dt-bindings/interrupt-controller/irq.h>
> @@ -162,4 +168,5 @@ gpio@c2f0000 {
>  	#gpio-cells = <2>;
>  	interrupt-controller;
>  	#interrupt-cells = <2>;
> +	timestamp-engine = <&tegra_hte_aon>;
>  };
> diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c
> index c026e7141e4e..6d1f15167529 100644
> --- a/drivers/gpio/gpio-tegra186.c
> +++ b/drivers/gpio/gpio-tegra186.c
> @@ -11,6 +11,7 @@
>  #include <linux/module.h>
>  #include <linux/of_device.h>
>  #include <linux/platform_device.h>
> +#include <linux/hte.h>
>  
>  #include <dt-bindings/gpio/tegra186-gpio.h>
>  #include <dt-bindings/gpio/tegra194-gpio.h>
> @@ -34,6 +35,7 @@
>  #define  TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_LEVEL BIT(4)
>  #define  TEGRA186_GPIO_ENABLE_CONFIG_DEBOUNCE BIT(5)
>  #define  TEGRA186_GPIO_ENABLE_CONFIG_INTERRUPT BIT(6)
> +#define  TEGRA186_GPIO_ENABLE_CONFIG_TIMESTAMP_FUNC BIT(7)
>  
>  #define TEGRA186_GPIO_DEBOUNCE_CONTROL 0x04
>  #define  TEGRA186_GPIO_DEBOUNCE_CONTROL_THRESHOLD(x) ((x) & 0xff)
> @@ -81,6 +83,7 @@ struct tegra_gpio {
>  	struct irq_chip intc;
>  	unsigned int num_irq;
>  	unsigned int *irq;
> +	struct device *dev;
>  
>  	const struct tegra_gpio_soc *soc;
>  	unsigned int num_irqs_per_bank;
> @@ -192,6 +195,86 @@ static int tegra186_gpio_direction_output(struct gpio_chip *chip,
>  	return 0;
>  }
>  
> +static int tegra186_gpio_req_hw_ts(struct gpio_chip *chip, unsigned int offset,
> +				   hte_ts_cb_t cb, hte_ts_threaded_cb_t tcb,
> +				   struct hte_ts_desc *hdesc, void *data)
> +{
> +	struct tegra_gpio *gpio;
> +	void __iomem *base;
> +	int value, ret;
> +
> +	if (!chip || !hdesc)
> +		return -EINVAL;
> +
> +	gpio = gpiochip_get_data(chip);
> +	if (!gpio)
> +		return -ENODEV;
> +
> +	base = tegra186_gpio_get_base(gpio, offset);
> +	if (WARN_ON(base == NULL))
> +		return -EINVAL;
> +
> +	/*
> +	 * HTE provider of this gpio controller does not support below gpio
> +	 * configs:
> +	 * 1. gpio as output
> +	 * 2. gpio as input
> +	 *
> +	 * HTE provider supports below gpio config:
> +	 * a. gpio as input with irq enabled
> +	 */
> +
> +	if (tegra186_gpio_get_direction(chip, offset) ==
> +	    GPIO_LINE_DIRECTION_OUT)
> +		return -ENOTSUPP;
> +
> +	if (!gpiochip_line_is_irq(chip, offset))
> +		return -ENOTSUPP;
> +
> +	hdesc->con_id = offset;
> +
> +	ret = hte_req_ts_by_hte_name(gpio->dev, "timestamp-engine", hdesc, cb,
> +				     tcb, data);
> +	if (ret)
> +		return ret;
> +
> +	value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG);
> +	value |= TEGRA186_GPIO_ENABLE_CONFIG_TIMESTAMP_FUNC;
> +	writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG);
> +
> +	return 0;
> +}
> +
> +static int tegra186_gpio_rel_hw_ts(struct gpio_chip *chip,
> +				   unsigned int offset,
> +				   struct hte_ts_desc *hdesc)
> +{
> +	struct tegra_gpio *gpio;
> +	void __iomem *base;
> +	int value, ret;
> +
> +	if (!hdesc || !chip)
> +		return -EINVAL;
> +
> +	gpio = gpiochip_get_data(chip);
> +	if (!gpio)
> +		return -ENODEV;
> +
> +	base = tegra186_gpio_get_base(gpio, offset);
> +	if (WARN_ON(base == NULL))
> +		return -EINVAL;
> +
> +	ret = hte_release_ts(hdesc);
> +	if (ret)
> +		return ret;
> +
> +	value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG);
> +	value &= ~TEGRA186_GPIO_ENABLE_CONFIG_TIMESTAMP_FUNC;
> +	writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG);
> +
> +	return 0;
> +}
> +
>  static int tegra186_gpio_get(struct gpio_chip *chip, unsigned int offset)
>  {
>  	struct tegra_gpio *gpio = gpiochip_get_data(chip);
> @@ -821,6 +904,12 @@ static int tegra186_gpio_probe(struct platform_device *pdev)
>  		offset += port->pins;
>  	}
>  
> +	gpio->dev = &pdev->dev;
> +	if (device_property_present(gpio->dev, "timestamp-engine")) {
> +		gpio->gpio.req_hw_timestamp = tegra186_gpio_req_hw_ts;
> +		gpio->gpio.rel_hw_timestamp = tegra186_gpio_rel_hw_ts;
> +	}
> +
>  	return devm_gpiochip_add_data(&pdev->dev, &gpio->gpio, gpio);
>  }
>  
> -- 
> 2.17.1
> 
> 

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC v2 01/11] Documentation: Add HTE subsystem guide
  2021-10-02  0:18   ` Randy Dunlap
@ 2021-11-03  0:36     ` Dipen Patel
  0 siblings, 0 replies; 33+ messages in thread
From: Dipen Patel @ 2021-11-03  0:36 UTC (permalink / raw)
  To: Randy Dunlap, thierry.reding, jonathanh, linux-kernel,
	linux-tegra, linux-gpio, linus.walleij, bgolaszewski, warthog618,
	devicetree, linux-doc, robh+dt

Hi Randy,

Thanks for the comments, will implement all your suggestions in RFC V3.

On 10/1/21 5:18 PM, Randy Dunlap wrote:
> On 9/30/21 4:26 PM, Dipen Patel wrote:
>> Adding hte document which can help understand various APIs implemented
>> in HTE framework for the HTE producers and the consumers.
>>
>> Signed-off-by: Dipen Patel <dipenp@nvidia.com>
>> ---
>> Changes in v2:
>> - Removed explanation, instead added kernel-doc references.
>>
>>   Documentation/hte/hte.rst | 83 +++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 83 insertions(+)
>>   create mode 100644 Documentation/hte/hte.rst
>>
>> diff --git a/Documentation/hte/hte.rst b/Documentation/hte/hte.rst
>> new file mode 100644
>> index 000000000000..c9b1badae601
>> --- /dev/null
>> +++ b/Documentation/hte/hte.rst
>> @@ -0,0 +1,83 @@
>> +============================================
>> +The Linux Hardware Timestamping Engine (HTE)
>> +============================================
>> +
>> +:Author: Dipen Patel
>> +
>> +Introduction
>> +------------
>> +
>> +Certain devices have built in hardware timestamping engines which can
>> +monitor sets of system signals, lines, buses etc... in realtime for state
>> +change; upon detecting the change they can automatically store the timestamp at
>> +the moment of occurrence. Such functionality may help achieve better accuracy
>> +in obtaining timestamp than using software counterparts i.e. ktime and friends.
>
>                 timestamps
>
>> +
>> +This document describes the API that can be used by hardware timestamping
>> +engine provider and consumer drivers that want to use the hardware timestamping
>> +engine (HTE) framework. Both consumers and providers must
>> +#include <linux/hte.h>.
>> +
>> +The HTE framework APIs for the providers
>> +----------------------------------------
>> +
>> +.. kernel-doc:: drivers/hte/hte.c
>> +   :functions: devm_hte_register_chip hte_push_ts_ns
>> +
>> +The HTE framework APIs for the consumers
>> +----------------------------------------
>> +
>> +.. kernel-doc:: drivers/hte/hte.c
>> +   :functions: devm_of_hte_request_ts hte_req_ts_by_hte_name hte_release_ts hte_enable_ts hte_disable_ts hte_get_clk_src_info
>> +
>> +The HTE framework public structures
>> +-----------------------------------
>> +.. kernel-doc:: include/linux/hte.h
>> +
>> +
>> +More on the HTE timestamp data
>> +------------------------------
>> +The struct hte_ts_data is used to pass timestamp details between the consumers
>> +and the providers. It expresses timestamp data in nano second in u64 data
>
>                                                      nanosesconds
>                                              possibly:           in a __u64 data
>
>> +type. For now all the HTE APIs using struct hte_ts_data requires tsc to be in
>
>                                                            require tsc to be in
>
>> +nano seconds. An example of the typical hte_ts_data data life cycle, for the
>
>    nanoseconds.
>
>> +GPIO line is as follows::
>> +
>> + - Monitors GPIO line change.
>> + - Detects the state change on GPIO line.
>> + - Converts timestamps in nano seconds and stores it in tsc.
>
>                              nanoseconds
>
>> + - Stores GPIO direction in dir variable if the provider has that hardware
>> + capability.
>> + - Pushes this hte_ts_data object to HTE subsystem.
>> + - HTE subsystem increments seq counter and invokes consumer provided callback.
>> + Based on callback return value, the HTE starts kernel thread and invokes
>
>                                             starts a kernel thread
>
>> + secondary callback in the thread context.
>> +
>> +HTE subsystem debugfs attributes
>> +--------------------------------
>> +HTE subsystem creates debugfs attributes at ``/sys/kernel/debug/hte/``.
>> +It also creates line/signal related debugfs attributes at
>
>                         signal-related
>
>> +``/sys/kernel/debug/hte/<provider>/<label or line id>/``.
>> +
>> +`ts_requested`
>> +        The total number of entities requested from the given provider,
>> +        where entity is the provider specific and could represent
>
>                      is specified by the provider and could
> (just guessing here; I could not parse it.)
>
>> +        lines, GPIO, chip signals, buses etc...
>> +                The attribute will be availble at
>
>                                  available
>
>> +        ``/sys/kernel/debug/hte/<provider>/``.
>> +
>> +        Read only value
>
>         Read-only value
>
>> +
>> +`total_ts`
>> +        The total number of entities supported by the provider.
>> +                The attribute will be availble at
>
>                                  available
>
>> +        ``/sys/kernel/debug/hte/<provider>/``.
>> +
>> +        Read only value
>
>         Read-only value
>
>> +
>> +`dropped_timestamps`
>> +        The dropped timestamps for a given line.
>> +                The attribute will be availble at
>
>                                  available
>
>> +        ``/sys/kernel/debug/hte/<provider>/<label or line id>/``.
>> +
>> +        Read only value
>
>         Read-only value
>>
>
>

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC v2 02/11] drivers: Add hardware timestamp engine (HTE)
  2021-10-01 23:53   ` Randy Dunlap
@ 2021-11-03  0:37     ` Dipen Patel
  0 siblings, 0 replies; 33+ messages in thread
From: Dipen Patel @ 2021-11-03  0:37 UTC (permalink / raw)
  To: Randy Dunlap, thierry.reding, jonathanh, linux-kernel,
	linux-tegra, linux-gpio, linus.walleij, bgolaszewski, warthog618,
	devicetree, linux-doc, robh+dt

Hi Randy,

I will implement all your suggestions in RFC v3.


Best Regards,

Dipen Patel

On 10/1/21 4:53 PM, Randy Dunlap wrote:
> On 9/30/21 4:26 PM, Dipen Patel wrote:
>> diff --git a/drivers/hte/Kconfig b/drivers/hte/Kconfig
>> new file mode 100644
>> index 000000000000..6fdf243d281b
>> --- /dev/null
>> +++ b/drivers/hte/Kconfig
>> @@ -0,0 +1,22 @@
>> +# SPDX-License-Identifier: GPL-2.0-only
>> +menuconfig HTE
>> +    bool "Hardware Timestamping Engine (HTE) Support"
>> +    help
>> +      Hardware Timestamping Engine (HTE) Support.
>> +
>> +      Some devices provide hardware timestamping engine which can timestamp
>
>                    provide a hardware
>
>> +      certain device lines/signals in realtime. This way to provide
>
>                                                 This provides a
>
>> +      hardware assisted timestamp to generic signals like GPIOs, IRQs lines
>
>       hardware-assisted                              like GPIOs or IRQ lines.
>
>
>> +      comes with benefit for the applications like autonomous machines
>
>       It comes with a benefit for applications like
>
>> +      needing accurate timestamping event with less jitter.
>> +
>> +      This framework provides a generic interface to such HTE devices
>> +      within the Linux kernel. It provides an API to register and
>> +      unregister a HTE provider chip, configurable sw buffer to
>
>                                                    software
>
>> +      store the timestamps, push the timestamp from the HTE providers and
>> +      retrieve timestamps for the consumers. It also provides means for the
>> +      consumers to request signals it wishes to hardware timestamp and
>> +      release them if not required.
>> +
>> +      If unsure, say no.
>
>
> HTH.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC v2 03/11] hte: Add tegra194 HTE kernel provider
  2021-10-02  0:07   ` Randy Dunlap
@ 2021-11-03  1:15     ` Dipen Patel
  0 siblings, 0 replies; 33+ messages in thread
From: Dipen Patel @ 2021-11-03  1:15 UTC (permalink / raw)
  To: Randy Dunlap, thierry.reding, jonathanh, linux-kernel,
	linux-tegra, linux-gpio, linus.walleij, bgolaszewski, warthog618,
	devicetree, linux-doc, robh+dt

Hi Randy,

Thanks for the comments. I will implement changes in RFC V3.

Best Regards,

Dipen Patel

On 10/1/21 5:07 PM, Randy Dunlap wrote:
> On 9/30/21 4:26 PM, Dipen Patel wrote:
>> diff --git a/Documentation/hte/tegra194-hte.rst b/Documentation/hte/tegra194-hte.rst
>> new file mode 100644
>> index 000000000000..fb229bda2408
>> --- /dev/null
>> +++ b/Documentation/hte/tegra194-hte.rst
>> @@ -0,0 +1,56 @@
>> +HTE Kernel provider driver
>> +==========================
>> +
>> +Description
>> +-----------
>> +The Nvidia tegra194 HTE provider driver implements two GTE
>> +(Generic Timestamping Engine) instances 1) GPIO GTE and 2) LIC IRQ GTE. The
>
>                                  instances:                                ^^Drop "The"
>
>> +both GTEs instances get the timestamp from the system counter TSC which has
>
>    Both
>
>> +31.25MHz clock rate, and the driver converts clock tick rate to nano seconds
>
>                                                                    nanoseconds
>
>> +before storing it as timestamp value.
>> +
>> +GPIO GTE
>> +--------
>> +
>> +This GTE instance timestamps GPIO in real time, for that to happen GPIO
>
>                                              time. For
>
>> +needs to be configured as input and IRQ needs to ba enabled. The only always on
>
>                                                     be
>
>> +(AON) gpio controller instance supports timestamping GPIOs in realtime and it
>
>          GPIO                                                    real time {or change
>                            the instance 3 lines above to be "realtime"}
>
>> +has 39 GPIO lines. The GPIO GTE and AON GPIO controller are tightly coupled as
>> +it requires very specific bits to be set in GPIO config register before GPIO> +GTE can be used. The GPIO GTE functionality is accessed from the GPIOLIB
>> +framework for the in kernel and userspace consumers. In the later case,
>
>                      in-kernel                                 latter
>
>> +requests go through GPIOLIB CDEV framework. The below APIs are added in GPIOLIB
>> +framework to access HTE subsystem and GPIO GTE.
>> +
>> +.. kernel-doc:: drivers/gpio/gpiolib.c
>> +   :functions: gpiod_req_hw_timestamp_ns gpiod_rel_hw_timestamp_ns
>> +
>> +There is hte-tegra194-gpio-test.c, located in ``drivers/hte/`` directory, test
>> +driver which demonstrates above APIs for the Jetson AGX platform.
>> +
>> +For userspace consumers, GPIO_V2_LINE_FLAG_EVENT_CLOCK_HARDWARE flag must be
>> +specifed during IOCTL calls, refer ``tools/gpio/gpio-event-mon.c``, which
>
>    specified             calls. Refer to
>
>> +returns the timestamp in nano second.
>
>                             nanoseconds.
>
>> +
>> +LIC IRQ GTE
>> +-----------
>> +
>> +This GTE instance timestamp LIC IRQ lines in real time. There are 352 IRQ
>
>                      timestamps                 ^^^^^^^^^ {be consistent}
>   (also (repeating a prior email) define "LIC")
>
>> +lines which this instance can help timestamp realtime. The hte devicetree
>
>                              can add timestamps to in realtime.
>
>> +binding described at ``Documentation/devicetree/bindings/hte/`` gives out
>
>                                                                    provides an
>
>> +example how consumer can request IRQ line, since it is one to one mapping,
>
>    example of how a consumer can request an IRQ line. Since it is a one-to-one mapping,
>
>> +consumers can simply specify IRQ number that they are interested in. There is
>
>                         specify the IRQ number
>
>> +no userspace consumer support for this GTE instance. The sample test code
>> +hte-tegra194-irq-test.c, located in ``drivers/hte/`` directory,
>
>                                     in the
>
>> +demonstrates how to use IRQ GTE instance. The below is sample device tree
>
>                 how to use an IRQ GTE instance.
>
>> +snippet code for the test driver::
>> +
>> + tegra_hte_irq_test {
>> +        compatible = "nvidia,tegra194-hte-irq-test";
>> +        htes = <&tegra_hte_lic 0x19>;
>> +        hte-names = "hte-lic";
>> + };
>> +
>> +The provider source code of both IRQ and GPIO GTE instances is locate at
>
>                                                                   located
>
>> +``drivers/hte/hte-tegra194.c``.
>> +
>
>

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC v2 07/11] gpio: tegra186: Add HTE in gpio-tegra186 driver
  2021-10-08 22:16   ` Rob Herring
@ 2021-11-03  5:05     ` Dipen Patel
  0 siblings, 0 replies; 33+ messages in thread
From: Dipen Patel @ 2021-11-03  5:05 UTC (permalink / raw)
  To: Rob Herring
  Cc: thierry.reding, jonathanh, linux-kernel, linux-tegra, linux-gpio,
	linus.walleij, bgolaszewski, warthog618, devicetree, linux-doc

Hi,


On 10/8/21 3:16 PM, Rob Herring wrote:
> On Thu, Sep 30, 2021 at 04:26:13PM -0700, Dipen Patel wrote:
>> Tegra194 AON GPIO controller with the use of its internal hardware
>> timestamping engine (HTE) also known as GTE can timestamp GPIO
>> lines through system counter. This patch implements two callbacks
>> which are essential for the gpio consumers that want such HTE
>> functionality. The callbacks details can be found at
>> include/gpio/driver.h.
>>
>> Since AON GPIO controller depends on HTE engine, it creates hardware
>> dependency between controller and AON HTE provider. To express that,
>> the optional devicetree property is introduced for AON GPIO controller.
>>
>> Signed-off-by: Dipen Patel <dipenp@nvidia.com>
>> ---
>>  .../bindings/gpio/nvidia,tegra186-gpio.txt    |  7 ++
> Bindings should be a separate patch. Consider converting this to schema 
> first too.

I will create separate patch. For the schema, I guess converting is out of the

scope in this patch series. I believe its better to create separate patch for that

task.

>>  drivers/gpio/gpio-tegra186.c                  | 89 +++++++++++++++++++
>>  2 files changed, 96 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/gpio/nvidia,tegra186-gpio.txt b/Documentation/devicetree/bindings/gpio/nvidia,tegra186-gpio.txt
>> index adff16c71d21..00a3e47ab560 100644
>> --- a/Documentation/devicetree/bindings/gpio/nvidia,tegra186-gpio.txt
>> +++ b/Documentation/devicetree/bindings/gpio/nvidia,tegra186-gpio.txt
>> @@ -127,6 +127,12 @@ Required properties:
>>              - 8: Active low level-sensitive.
>>              Valid combinations are 1, 2, 3, 4, 8.
>>  
>> +Optional properties:
>> +- timestamp-engine
> Should be in the common binding.
>
> But then when do you use hardware-timestamps? This property seems to 
> assume GPIO hand the timestamp engine have the same numbering of 
> signals. I think you need to be able to map GPIOx to timestamp y. If you 
> want a short cut for a 1-1 case, then that's another discussion.

The mapping is done in the GPIO HTE provider if its not one-to-one. An example is

hte-tegra194.c (tegra194_aon_gpio_map) in this patch series.

>> +    AON GPIO controller has timestamp engine which can hardware timestamp
>> +    GPIO configured as input and IRQ. This property specifies hardware
>> +    timestamp engine (HTE) device-tree node.
>> +
>>  Example:
>>  
>>  #include <dt-bindings/interrupt-controller/irq.h>
>> @@ -162,4 +168,5 @@ gpio@c2f0000 {
>>  	#gpio-cells = <2>;
>>  	interrupt-controller;
>>  	#interrupt-cells = <2>;
>> +	timestamp-engine = <&tegra_hte_aon>;
>>  };
>> diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c
>> index c026e7141e4e..6d1f15167529 100644
>> --- a/drivers/gpio/gpio-tegra186.c
>> +++ b/drivers/gpio/gpio-tegra186.c
>> @@ -11,6 +11,7 @@
>>  #include <linux/module.h>
>>  #include <linux/of_device.h>
>>  #include <linux/platform_device.h>
>> +#include <linux/hte.h>
>>  
>>  #include <dt-bindings/gpio/tegra186-gpio.h>
>>  #include <dt-bindings/gpio/tegra194-gpio.h>
>> @@ -34,6 +35,7 @@
>>  #define  TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_LEVEL BIT(4)
>>  #define  TEGRA186_GPIO_ENABLE_CONFIG_DEBOUNCE BIT(5)
>>  #define  TEGRA186_GPIO_ENABLE_CONFIG_INTERRUPT BIT(6)
>> +#define  TEGRA186_GPIO_ENABLE_CONFIG_TIMESTAMP_FUNC BIT(7)
>>  
>>  #define TEGRA186_GPIO_DEBOUNCE_CONTROL 0x04
>>  #define  TEGRA186_GPIO_DEBOUNCE_CONTROL_THRESHOLD(x) ((x) & 0xff)
>> @@ -81,6 +83,7 @@ struct tegra_gpio {
>>  	struct irq_chip intc;
>>  	unsigned int num_irq;
>>  	unsigned int *irq;
>> +	struct device *dev;
>>  
>>  	const struct tegra_gpio_soc *soc;
>>  	unsigned int num_irqs_per_bank;
>> @@ -192,6 +195,86 @@ static int tegra186_gpio_direction_output(struct gpio_chip *chip,
>>  	return 0;
>>  }
>>  
>> +static int tegra186_gpio_req_hw_ts(struct gpio_chip *chip, unsigned int offset,
>> +				   hte_ts_cb_t cb, hte_ts_threaded_cb_t tcb,
>> +				   struct hte_ts_desc *hdesc, void *data)
>> +{
>> +	struct tegra_gpio *gpio;
>> +	void __iomem *base;
>> +	int value, ret;
>> +
>> +	if (!chip || !hdesc)
>> +		return -EINVAL;
>> +
>> +	gpio = gpiochip_get_data(chip);
>> +	if (!gpio)
>> +		return -ENODEV;
>> +
>> +	base = tegra186_gpio_get_base(gpio, offset);
>> +	if (WARN_ON(base == NULL))
>> +		return -EINVAL;
>> +
>> +	/*
>> +	 * HTE provider of this gpio controller does not support below gpio
>> +	 * configs:
>> +	 * 1. gpio as output
>> +	 * 2. gpio as input
>> +	 *
>> +	 * HTE provider supports below gpio config:
>> +	 * a. gpio as input with irq enabled
>> +	 */
>> +
>> +	if (tegra186_gpio_get_direction(chip, offset) ==
>> +	    GPIO_LINE_DIRECTION_OUT)
>> +		return -ENOTSUPP;
>> +
>> +	if (!gpiochip_line_is_irq(chip, offset))
>> +		return -ENOTSUPP;
>> +
>> +	hdesc->con_id = offset;
>> +
>> +	ret = hte_req_ts_by_hte_name(gpio->dev, "timestamp-engine", hdesc, cb,
>> +				     tcb, data);
>> +	if (ret)
>> +		return ret;
>> +
>> +	value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG);
>> +	value |= TEGRA186_GPIO_ENABLE_CONFIG_TIMESTAMP_FUNC;
>> +	writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG);
>> +
>> +	return 0;
>> +}
>> +
>> +static int tegra186_gpio_rel_hw_ts(struct gpio_chip *chip,
>> +				   unsigned int offset,
>> +				   struct hte_ts_desc *hdesc)
>> +{
>> +	struct tegra_gpio *gpio;
>> +	void __iomem *base;
>> +	int value, ret;
>> +
>> +	if (!hdesc || !chip)
>> +		return -EINVAL;
>> +
>> +	gpio = gpiochip_get_data(chip);
>> +	if (!gpio)
>> +		return -ENODEV;
>> +
>> +	base = tegra186_gpio_get_base(gpio, offset);
>> +	if (WARN_ON(base == NULL))
>> +		return -EINVAL;
>> +
>> +	ret = hte_release_ts(hdesc);
>> +	if (ret)
>> +		return ret;
>> +
>> +	value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG);
>> +	value &= ~TEGRA186_GPIO_ENABLE_CONFIG_TIMESTAMP_FUNC;
>> +	writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG);
>> +
>> +	return 0;
>> +}
>> +
>>  static int tegra186_gpio_get(struct gpio_chip *chip, unsigned int offset)
>>  {
>>  	struct tegra_gpio *gpio = gpiochip_get_data(chip);
>> @@ -821,6 +904,12 @@ static int tegra186_gpio_probe(struct platform_device *pdev)
>>  		offset += port->pins;
>>  	}
>>  
>> +	gpio->dev = &pdev->dev;
>> +	if (device_property_present(gpio->dev, "timestamp-engine")) {
>> +		gpio->gpio.req_hw_timestamp = tegra186_gpio_req_hw_ts;
>> +		gpio->gpio.rel_hw_timestamp = tegra186_gpio_rel_hw_ts;
>> +	}
>> +
>>  	return devm_gpiochip_add_data(&pdev->dev, &gpio->gpio, gpio);
>>  }
>>  
>> -- 
>> 2.17.1
>>
>>

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC v2 10/11] hte: Add tegra GPIO HTE test driver
  2021-10-01 23:47   ` Randy Dunlap
@ 2021-11-03  5:07     ` Dipen Patel
  0 siblings, 0 replies; 33+ messages in thread
From: Dipen Patel @ 2021-11-03  5:07 UTC (permalink / raw)
  To: Randy Dunlap, thierry.reding, jonathanh, linux-kernel,
	linux-tegra, linux-gpio, linus.walleij, bgolaszewski, warthog618,
	devicetree, linux-doc, robh+dt

Hi,


On 10/1/21 4:47 PM, Randy Dunlap wrote:
> Hi,
>
> On 9/30/21 4:26 PM, Dipen Patel wrote:
>> diff --git a/drivers/hte/Kconfig b/drivers/hte/Kconfig
>> index eb339526f141..57c97034d187 100644
>> --- a/drivers/hte/Kconfig
>> +++ b/drivers/hte/Kconfig
>> @@ -38,4 +38,13 @@ config HTE_TEGRA194_IRQ_TEST
>>         The NVIDIA Tegra194 GTE IRQ test driver demonstrates HTE subsystem
>>         usage for the LIC IRQ hardware timestamp.
>>   +config HTE_TEGRA194_GPIO_TEST
>> +        tristate "NVIDIA Tegra194 HTE GPIO Test"
>> +        depends on HTE_TEGRA194
>> +        help
>> +      The NVIDIA Tegra194 GTE GPIO test driver demonstrates how to use HTE
>
>                                                                 to use the HTE
>
>> +      subsystem indirectly through gpiolib API calls for GPIO line for the
>
>                                                               lines
>
>> +      hardware assisted timestamping.
>
>       hardware-assisted
>
>> +
>>   endif
>
> Also:
>
> Please follow coding-style for Kconfig files:
>
> (from Documentation/process/coding-style.rst, section 10):
>
> For all of the Kconfig* configuration files throughout the source tree,
> the indentation is somewhat different.  Lines under a ``config`` definition
> are indented with one tab, while help text is indented an additional two
> spaces.
>
> Some of the lines above are indented with spaces instead of one tab.
>
I will double check this. From the RFCv1 comments, I did correct formatting according

to above coding style i.e. everything 1 tab except help which is 1 tab + 2 spaces.

>
> thanks.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC v2 04/11] dt-bindings: Add HTE bindings
  2021-10-08 22:11   ` Rob Herring
@ 2021-11-03 21:43     ` Dipen Patel
  0 siblings, 0 replies; 33+ messages in thread
From: Dipen Patel @ 2021-11-03 21:43 UTC (permalink / raw)
  To: Rob Herring
  Cc: thierry.reding, jonathanh, linux-kernel, linux-tegra, linux-gpio,
	linus.walleij, bgolaszewski, warthog618, devicetree, linux-doc

Hi Rob,


On 10/8/21 3:11 PM, Rob Herring wrote:
> On Thu, Sep 30, 2021 at 04:26:10PM -0700, Dipen Patel wrote:
>> Introduces HTE devicetree binding details for the HTE subsystem. It
>> includes examples for the consumers, binding details for the providers
>> and specific binding details for the Tegra194 based HTE providers.
>>
> This pattern of binding isn't easily checked completely by schema. You 
> need a dtc check added too. Should be a 2 line change. (And dtc changes 
> go upstream first).
Sorry, I could not understand your comment. Can you please elaborate?
>
>> Signed-off-by: Dipen Patel <dipenp@nvidia.com>
>> ---
>> Changes in v2:
>> - Replace hte with hardware-timestamp for property names
>> - Renamed file
>> - Removed example from the common dt binding file.
>>
>>  .../hte/hardware-timestamps-common.yaml       | 29 +++++++
>>  .../devicetree/bindings/hte/hte-consumer.yaml | 48 +++++++++++
>>  .../bindings/hte/nvidia,tegra194-hte.yaml     | 79 +++++++++++++++++++
>>  3 files changed, 156 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/hte/hardware-timestamps-common.yaml
>>  create mode 100644 Documentation/devicetree/bindings/hte/hte-consumer.yaml
>>  create mode 100644 Documentation/devicetree/bindings/hte/nvidia,tegra194-hte.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/hte/hardware-timestamps-common.yaml b/Documentation/devicetree/bindings/hte/hardware-timestamps-common.yaml
>> new file mode 100644
>> index 000000000000..8b8db3bc4dcf
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/hte/hardware-timestamps-common.yaml
>> @@ -0,0 +1,29 @@
>> +# SPDX-License-Identifier: GPL-2.0
> Dual license new bindings.
Do you mean to add SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) instead?
>
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/hte/hardware-timestamps-common.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Hardware timestamp providers
>> +
>> +maintainers:
>> +  - Dipen Patel <dipenp@nvidia.com>
>> +
>> +description: |
>> +  Some devices/SoCs have hardware time stamping engines which can use hardware
>> +  means to timestamp entity in realtime. The entity could be anything from
>> +  GPIOs, IRQs, Bus and so on. The hardware timestamp engine (HTE) present
>> +  itself as a provider with the bindings described in this document.
>> +
>> +properties:
>> +  $nodename:
>> +    pattern: "^hardware-timestamps(@.*|-[0-9a-f])*$"
> "^hardware-timestamp(@.*|-[0-9a-f])?$"
>
>> +
>> +  "#hardware-timestamps-cells":
> Double plural:
>
> #hardware-timestamp-cells
>
> Arguably, the same string everywhere would have been an easier design, 
> but let's keep consistency with (most) other flavors of this pattern.
>
>> +    description:
>> +      Number of cells in a HTE specifier.
>> +
>> +required:
>> +  - "#hardware-timestamps-cells"
>> +
>> +additionalProperties: true
>> diff --git a/Documentation/devicetree/bindings/hte/hte-consumer.yaml b/Documentation/devicetree/bindings/hte/hte-consumer.yaml
>> new file mode 100644
>> index 000000000000..cf65d1d44a18
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/hte/hte-consumer.yaml
>> @@ -0,0 +1,48 @@
>> +# SPDX-License-Identifier: GPL-2.0
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/hte/hte-consumer.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: HTE Consumer Device Tree Bindings
>> +
>> +maintainers:
>> +  - Dipen Patel <dipenp@nvidia.com>
>> +
>> +description: |
>> +  HTE properties should be named "hardware-timestamps". The exact meaning of
>> +  each hardware-timestamps property must be documented in the device tree
>> +  binding for each device. An optional property "hardware-timestamps-names" may
>> +  contain a list of strings to label each of the HTE devices listed in the
>> +  "hardware-timestamps" property.
>> +
>> +  The "hardware-timestamps-names" property if specified is used to map the name
>> +  of the HTE device requested by the devm_of_hte_request_ts() or of_hte_request_ts
>> +  call to an index into the list given by the "hardware-timestamps" property.
>> +
>> +properties:
>> +  hardware-timestamps:
>> +    $ref: /schemas/types.yaml#/definitions/phandle-array
>> +    description:
>> +      The list of HTE provider phandle. The provider must document the number
>> +      of cell that must be passed in this property along with phandle.
>> +
>> +  hardware-timestamps-names:
> hardware-timestamp-names
>
>
>> +    $ref: /schemas/types.yaml#/definitions/string-array
>> +    description:
>> +      An optional string property.
>> +
>> +required:
>> +  - "hardware-timestamps"
> Don't need quotes.
>
>> +
>> +dependencies:
>> +  hardware-timestamps-names: [ hardware-timestamps ]
>> +
>> +additionalProperties: true
>> +
>> +examples:
>> +  - |
>> +    hte_irq_consumer {
>> +              hardware-timestamps = <&tegra_hte_lic 0x19>;
>> +              hardware-timestamps-names = "hte-irq";
>> +    };
>> diff --git a/Documentation/devicetree/bindings/hte/nvidia,tegra194-hte.yaml b/Documentation/devicetree/bindings/hte/nvidia,tegra194-hte.yaml
>> new file mode 100644
>> index 000000000000..529926118f35
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/hte/nvidia,tegra194-hte.yaml
>> @@ -0,0 +1,79 @@
>> +# SPDX-License-Identifier: GPL-2.0
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/hte/nvidia,tegra194-hte.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Tegra194 on chip generic hardware timestamping engine (HTE)
>> +
>> +maintainers:
>> +  - Dipen Patel <dipenp@nvidia.com>
>> +
>> +description: |
>> +  Tegra194 SoC has multiple generic hardware timestamping engines which can
>> +  monitor subset of GPIO and on chip IRQ lines for the state change, upon
>> +  detection it will record timestamp (taken from system counter) in its
>> +  internal hardware FIFO. It has bitmap array arranged in 32bit slices where
> has a bitmap
>
>> +  each bit represent signal/line to enable or disable for the hardware
>> +  timestamping.
>> +
>> +properties:
>> +  compatible:
>> +    enum:
>> +      - nvidia,tegra194-gte-aon
>> +      - nvidia,tegra194-gte-lic
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +  interrupts:
>> +    maxItems: 1
>> +
>> +  int-threshold:
> nvidia,int-threshold unless this is common for all hw timestamps?
>
>> +    description:
>> +      HTE device generates its interrupt based on this u32 FIFO threshold
>> +      value. The recommended value is 1.
>> +    minimum: 1
>> +    maximum: 256
>> +
>> +  slices:
> nvidia,slices
>
> Needs a type.
>
>> +    description:
>> +      HTE lines are arranged in 32 bit slice where each bit represents different
>> +      line/signal that it can enable/configure for the timestamp. It is u32
>> +      property and depends on the HTE instance in the chip.
>> +    enum: [3, 11]
>> +
>> +  '#hardware-timestamps-cells':
>> +    const: 1
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - interrupts
>> +  - slices
>> +  - "#hardware-timestamps-cells"
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> +  - |
>> +    tegra_hte_aon: hardware-timestamps@c1e0000 {
>> +              compatible = "nvidia,tegra194-gte-aon";
>> +              reg = <0xc1e0000 0x10000>;
>> +              interrupts = <0 13 0x4>;
>> +              int-threshold = <1>;
>> +              slices = <3>;
>> +              #hardware-timestamps-cells = <1>;
>> +    };
>> +
>> +  - |
>> +    tegra_hte_lic: hardware-timestamps@3aa0000 {
>> +              compatible = "nvidia,tegra194-gte-lic";
>> +              reg = <0x3aa0000 0x10000>;
>> +              interrupts = <0 11 0x4>;
>> +              int-threshold = <1>;
>> +              slices = <11>;
>> +              #hardware-timestamps-cells = <1>;
>> +    };
>> +
>> +...
>> -- 
>> 2.17.1
>>
>>

^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2021-11-03 21:43 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-30 23:26 [RFC v2 00/11] Intro to Hardware timestamping engine Dipen Patel
2021-09-30 23:26 ` [RFC v2 01/11] Documentation: Add HTE subsystem guide Dipen Patel
2021-10-02  0:18   ` Randy Dunlap
2021-11-03  0:36     ` Dipen Patel
2021-09-30 23:26 ` [RFC v2 02/11] drivers: Add hardware timestamp engine (HTE) Dipen Patel
2021-10-01 23:53   ` Randy Dunlap
2021-11-03  0:37     ` Dipen Patel
2021-09-30 23:26 ` [RFC v2 03/11] hte: Add tegra194 HTE kernel provider Dipen Patel
2021-10-01 23:44   ` Randy Dunlap
2021-10-02  0:07   ` Randy Dunlap
2021-11-03  1:15     ` Dipen Patel
2021-09-30 23:26 ` [RFC v2 04/11] dt-bindings: Add HTE bindings Dipen Patel
2021-10-03 21:53   ` Linus Walleij
2021-10-08 22:11   ` Rob Herring
2021-11-03 21:43     ` Dipen Patel
2021-09-30 23:26 ` [RFC v2 05/11] hte: Add Tegra194 IRQ HTE test driver Dipen Patel
2021-09-30 23:26 ` [RFC v2 06/11] gpiolib: Add HTE support Dipen Patel
2021-10-01  9:19   ` kernel test robot
2021-10-03 22:01   ` Linus Walleij
2021-09-30 23:26 ` [RFC v2 07/11] gpio: tegra186: Add HTE in gpio-tegra186 driver Dipen Patel
2021-10-08 22:16   ` Rob Herring
2021-11-03  5:05     ` Dipen Patel
2021-09-30 23:26 ` [RFC v2 08/11] gpiolib: cdev: Add hardware timestamp clock type Dipen Patel
2021-10-03 21:59   ` Linus Walleij
2021-10-03 22:09   ` Linus Walleij
2021-09-30 23:26 ` [RFC v2 09/11] tools: gpio: Add new hardware " Dipen Patel
2021-10-03 22:02   ` Linus Walleij
2021-09-30 23:26 ` [RFC v2 10/11] hte: Add tegra GPIO HTE test driver Dipen Patel
2021-10-01 23:47   ` Randy Dunlap
2021-11-03  5:07     ` Dipen Patel
2021-09-30 23:26 ` [RFC v2 11/11] MAINTAINERS: Added HTE Subsystem Dipen Patel
2021-10-02  0:08   ` Randy Dunlap
2021-10-02  4:00     ` Joe Perches

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.