All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lizhi Hou <lizhi.hou@xilinx.com>
To: <linux-kernel@vger.kernel.org>
Cc: Lizhi Hou <lizhi.hou@xilinx.com>, <linux-fpga@vger.kernel.org>,
	<maxz@xilinx.com>, <sonal.santan@xilinx.com>, <yliu@xilinx.com>,
	<michal.simek@xilinx.com>, <stefanos@xilinx.com>,
	<devicetree@vger.kernel.org>, <trix@redhat.com>, <mdf@kernel.org>,
	<robh@kernel.org>, Max Zhen <max.zhen@xilinx.com>
Subject: [PATCH V7 XRT Alveo 17/20] fpga: xrt: clock frequency counter driver
Date: Thu, 27 May 2021 17:49:56 -0700	[thread overview]
Message-ID: <20210528004959.61354-18-lizhi.hou@xilinx.com> (raw)
In-Reply-To: <20210528004959.61354-1-lizhi.hou@xilinx.com>

Add clock frequency counter driver. Clock frequency counter is
a hardware function discovered by walking xclbin metadata. A xrt
device node will be created for it. Other part of driver can read the
actual clock frequency through clock frequency counter driver.

Signed-off-by: Sonal Santan <sonal.santan@xilinx.com>
Signed-off-by: Max Zhen <max.zhen@xilinx.com>
Signed-off-by: Lizhi Hou <lizhi.hou@xilinx.com>
Reviewed-by: Tom Rix <trix@redhat.com>
---
 drivers/fpga/xrt/include/xleaf/clkfreq.h |  21 +++
 drivers/fpga/xrt/lib/xleaf/clkfreq.c     | 223 +++++++++++++++++++++++
 2 files changed, 244 insertions(+)
 create mode 100644 drivers/fpga/xrt/include/xleaf/clkfreq.h
 create mode 100644 drivers/fpga/xrt/lib/xleaf/clkfreq.c

diff --git a/drivers/fpga/xrt/include/xleaf/clkfreq.h b/drivers/fpga/xrt/include/xleaf/clkfreq.h
new file mode 100644
index 000000000000..005441d5df78
--- /dev/null
+++ b/drivers/fpga/xrt/include/xleaf/clkfreq.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *	Lizhi Hou <Lizhi.Hou@xilinx.com>
+ */
+
+#ifndef _XRT_CLKFREQ_H_
+#define _XRT_CLKFREQ_H_
+
+#include "xleaf.h"
+
+/*
+ * CLKFREQ driver leaf calls.
+ */
+enum xrt_clkfreq_leaf_cmd {
+	XRT_CLKFREQ_READ = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
+};
+
+#endif	/* _XRT_CLKFREQ_H_ */
diff --git a/drivers/fpga/xrt/lib/xleaf/clkfreq.c b/drivers/fpga/xrt/lib/xleaf/clkfreq.c
new file mode 100644
index 000000000000..3d1f11152375
--- /dev/null
+++ b/drivers/fpga/xrt/lib/xleaf/clkfreq.c
@@ -0,0 +1,223 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Alveo FPGA Clock Frequency Counter Driver
+ *
+ * Copyright (C) 2020-2021 Xilinx, Inc.
+ *
+ * Authors:
+ *      Lizhi Hou<Lizhi.Hou@xilinx.com>
+ */
+
+#include <linux/mod_devicetable.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/regmap.h>
+#include <linux/io.h>
+#include "metadata.h"
+#include "xleaf.h"
+#include "xleaf/clkfreq.h"
+
+#define CLKFREQ_ERR(clkfreq, fmt, arg...)   \
+	xrt_err((clkfreq)->xdev, fmt "\n", ##arg)
+#define CLKFREQ_WARN(clkfreq, fmt, arg...)  \
+	xrt_warn((clkfreq)->xdev, fmt "\n", ##arg)
+#define CLKFREQ_INFO(clkfreq, fmt, arg...)  \
+	xrt_info((clkfreq)->xdev, fmt "\n", ##arg)
+#define CLKFREQ_DBG(clkfreq, fmt, arg...)   \
+	xrt_dbg((clkfreq)->xdev, fmt "\n", ##arg)
+
+#define XRT_CLKFREQ		"xrt_clkfreq"
+
+#define XRT_CLKFREQ_CONTROL_STATUS_MASK		0xffff
+
+#define XRT_CLKFREQ_CONTROL_START	0x1
+#define XRT_CLKFREQ_CONTROL_DONE	0x2
+#define XRT_CLKFREQ_V5_CLK0_ENABLED	0x10000
+
+#define XRT_CLKFREQ_CONTROL_REG		0
+#define XRT_CLKFREQ_COUNT_REG		0x8
+#define XRT_CLKFREQ_V5_COUNT_REG	0x10
+
+#define XRT_CLKFREQ_READ_RETRIES	10
+
+XRT_DEFINE_REGMAP_CONFIG(clkfreq_regmap_config);
+
+struct clkfreq {
+	struct xrt_device	*xdev;
+	struct regmap		*regmap;
+	const char		*clkfreq_ep_name;
+	struct mutex		clkfreq_lock; /* clock counter dev lock */
+};
+
+static int clkfreq_read(struct clkfreq *clkfreq, u32 *freq)
+{
+	int times = XRT_CLKFREQ_READ_RETRIES;
+	u32 status;
+	int ret;
+
+	*freq = 0;
+	mutex_lock(&clkfreq->clkfreq_lock);
+	ret = regmap_write(clkfreq->regmap, XRT_CLKFREQ_CONTROL_REG, XRT_CLKFREQ_CONTROL_START);
+	if (ret) {
+		CLKFREQ_INFO(clkfreq, "write start to control reg failed %d", ret);
+		goto failed;
+	}
+	while (times != 0) {
+		ret = regmap_read(clkfreq->regmap, XRT_CLKFREQ_CONTROL_REG, &status);
+		if (ret) {
+			CLKFREQ_INFO(clkfreq, "read control reg failed %d", ret);
+			goto failed;
+		}
+		if ((status & XRT_CLKFREQ_CONTROL_STATUS_MASK) == XRT_CLKFREQ_CONTROL_DONE)
+			break;
+		mdelay(1);
+		times--;
+	};
+
+	if (!times) {
+		ret = -ETIMEDOUT;
+		goto failed;
+	}
+
+	if (status & XRT_CLKFREQ_V5_CLK0_ENABLED)
+		ret = regmap_read(clkfreq->regmap, XRT_CLKFREQ_V5_COUNT_REG, freq);
+	else
+		ret = regmap_read(clkfreq->regmap, XRT_CLKFREQ_COUNT_REG, freq);
+	if (ret) {
+		CLKFREQ_INFO(clkfreq, "read count failed %d", ret);
+		goto failed;
+	}
+
+	mutex_unlock(&clkfreq->clkfreq_lock);
+
+	return 0;
+
+failed:
+	mutex_unlock(&clkfreq->clkfreq_lock);
+
+	return ret;
+}
+
+static ssize_t freq_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct clkfreq *clkfreq = xrt_get_drvdata(to_xrt_dev(dev));
+	ssize_t count;
+	u32 freq;
+
+	if (clkfreq_read(clkfreq, &freq))
+		return -EINVAL;
+
+	count = snprintf(buf, 64, "%u\n", freq);
+
+	return count;
+}
+static DEVICE_ATTR_RO(freq);
+
+static struct attribute *clkfreq_attrs[] = {
+	&dev_attr_freq.attr,
+	NULL,
+};
+
+static struct attribute_group clkfreq_attr_group = {
+	.attrs = clkfreq_attrs,
+};
+
+static int
+xrt_clkfreq_leaf_call(struct xrt_device *xdev, u32 cmd, void *arg)
+{
+	struct clkfreq *clkfreq;
+	int ret = 0;
+
+	clkfreq = xrt_get_drvdata(xdev);
+
+	switch (cmd) {
+	case XRT_XLEAF_EVENT:
+		/* Does not handle any event. */
+		break;
+	case XRT_CLKFREQ_READ:
+		ret = clkfreq_read(clkfreq, arg);
+		break;
+	default:
+		xrt_err(xdev, "unsupported cmd %d", cmd);
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+static void clkfreq_remove(struct xrt_device *xdev)
+{
+	sysfs_remove_group(&xdev->dev.kobj, &clkfreq_attr_group);
+}
+
+static int clkfreq_probe(struct xrt_device *xdev)
+{
+	struct clkfreq *clkfreq = NULL;
+	void __iomem *base = NULL;
+	struct resource *res;
+	int ret;
+
+	clkfreq = devm_kzalloc(&xdev->dev, sizeof(*clkfreq), GFP_KERNEL);
+	if (!clkfreq)
+		return -ENOMEM;
+
+	xrt_set_drvdata(xdev, clkfreq);
+	clkfreq->xdev = xdev;
+	mutex_init(&clkfreq->clkfreq_lock);
+
+	res = xrt_get_resource(xdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		ret = -EINVAL;
+		goto failed;
+	}
+	base = devm_ioremap_resource(&xdev->dev, res);
+	if (IS_ERR(base)) {
+		ret = PTR_ERR(base);
+		goto failed;
+	}
+
+	clkfreq->regmap = devm_regmap_init_mmio(&xdev->dev, base, &clkfreq_regmap_config);
+	if (IS_ERR(clkfreq->regmap)) {
+		CLKFREQ_ERR(clkfreq, "regmap %pR failed", res);
+		ret = PTR_ERR(clkfreq->regmap);
+		goto failed;
+	}
+	clkfreq->clkfreq_ep_name = res->name;
+
+	ret = sysfs_create_group(&xdev->dev.kobj, &clkfreq_attr_group);
+	if (ret) {
+		CLKFREQ_ERR(clkfreq, "create clkfreq attrs failed: %d", ret);
+		goto failed;
+	}
+
+	CLKFREQ_INFO(clkfreq, "successfully initialized clkfreq subdev");
+
+	return 0;
+
+failed:
+	return ret;
+}
+
+static struct xrt_dev_endpoints xrt_clkfreq_endpoints[] = {
+	{
+		.xse_names = (struct xrt_dev_ep_names[]) {
+			{ .compat = XRT_MD_COMPAT_CLKFREQ },
+			{ NULL },
+		},
+		.xse_min_ep = 1,
+	},
+	{ 0 },
+};
+
+static struct xrt_driver xrt_clkfreq_driver = {
+	.driver = {
+		.name = XRT_CLKFREQ,
+	},
+	.subdev_id = XRT_SUBDEV_CLKFREQ,
+	.endpoints = xrt_clkfreq_endpoints,
+	.probe = clkfreq_probe,
+	.remove = clkfreq_remove,
+	.leaf_call = xrt_clkfreq_leaf_call,
+};
+
+XRT_LEAF_INIT_FINI_FUNC(clkfreq);
-- 
2.27.0


  parent reply	other threads:[~2021-05-28  0:53 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-28  0:49 [PATCH V7 XRT Alveo 00/20] XRT Alveo driver overview Lizhi Hou
2021-05-28  0:49 ` [PATCH V7 XRT Alveo 01/20] Documentation: fpga: Add a document describing XRT Alveo drivers Lizhi Hou
2021-05-28  0:49 ` [PATCH V7 XRT Alveo 02/20] fpga: xrt: driver metadata helper functions Lizhi Hou
2021-05-28  0:49 ` [PATCH V7 XRT Alveo 03/20] fpga: xrt: xclbin file " Lizhi Hou
2021-05-28  0:49 ` [PATCH V7 XRT Alveo 04/20] fpga: xrt: xrt-lib driver manager Lizhi Hou
2021-05-28  0:49 ` [PATCH V7 XRT Alveo 05/20] fpga: xrt: group driver Lizhi Hou
2021-05-28  0:49 ` [PATCH V7 XRT Alveo 06/20] fpga: xrt: char dev node helper functions Lizhi Hou
2021-05-28  0:49 ` [PATCH V7 XRT Alveo 07/20] fpga: xrt: root driver infrastructure Lizhi Hou
2021-05-28  0:49 ` [PATCH V7 XRT Alveo 08/20] fpga: xrt: " Lizhi Hou
2021-05-28  0:49 ` [PATCH V7 XRT Alveo 09/20] fpga: xrt: management physical function driver (root) Lizhi Hou
2021-05-28  0:49 ` [PATCH V7 XRT Alveo 10/20] fpga: xrt: main driver for management function device Lizhi Hou
2021-05-28  0:49 ` [PATCH V7 XRT Alveo 11/20] fpga: xrt: fpga-mgr and region implementation for xclbin download Lizhi Hou
2021-05-28  0:49 ` [PATCH V7 XRT Alveo 12/20] fpga: xrt: VSEC driver Lizhi Hou
2021-05-28  0:49 ` [PATCH V7 XRT Alveo 13/20] fpga: xrt: User Clock Subsystem driver Lizhi Hou
2021-05-28  0:49 ` [PATCH V7 XRT Alveo 14/20] fpga: xrt: ICAP driver Lizhi Hou
2021-05-28  0:49 ` [PATCH V7 XRT Alveo 15/20] fpga: xrt: devctl xrt driver Lizhi Hou
2021-05-28  0:49 ` [PATCH V7 XRT Alveo 16/20] fpga: xrt: clock driver Lizhi Hou
2021-05-28  0:49 ` Lizhi Hou [this message]
2021-05-28  0:49 ` [PATCH V7 XRT Alveo 18/20] fpga: xrt: DDR calibration driver Lizhi Hou
2021-05-28  0:49 ` [PATCH V7 XRT Alveo 19/20] fpga: xrt: partition isolation driver Lizhi Hou
2021-05-28  0:49 ` [PATCH V7 XRT Alveo 20/20] fpga: xrt: Kconfig and Makefile updates for XRT drivers Lizhi Hou
2021-06-02 22:34 ` [PATCH V7 XRT Alveo 00/20] XRT Alveo driver overview Lizhi Hou
2021-06-03 14:23   ` RFC : " Tom Rix
2021-06-10 23:36     ` Lizhi Hou
2021-06-11 12:46       ` Tom Rix
2021-07-01 20:32 ` Tom Rix
2021-07-16 18:27   ` Tom Rix
2021-07-16 19:14     ` Lizhi Hou
2021-07-16 20:36       ` Tom Rix
2021-07-19 21:22         ` Lizhi Hou

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210528004959.61354-18-lizhi.hou@xilinx.com \
    --to=lizhi.hou@xilinx.com \
    --cc=devicetree@vger.kernel.org \
    --cc=linux-fpga@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=max.zhen@xilinx.com \
    --cc=maxz@xilinx.com \
    --cc=mdf@kernel.org \
    --cc=michal.simek@xilinx.com \
    --cc=robh@kernel.org \
    --cc=sonal.santan@xilinx.com \
    --cc=stefanos@xilinx.com \
    --cc=trix@redhat.com \
    --cc=yliu@xilinx.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.