From: Alexander Shishkin <alexander.shishkin@linux.intel.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: linux-kernel@vger.kernel.org, mathieu.poirier@linaro.org,
pebolle@tiscali.nl, peter.lachner@intel.com,
norbert.schulz@intel.com, keven.boell@intel.com,
yann.fouassier@intel.com, laurent.fert@intel.com,
Alexander Shishkin <alexander.shishkin@linux.intel.com>
Subject: [PATCH v1 08/11] intel_th: Add Software Trace Hub driver
Date: Fri, 20 Mar 2015 19:29:55 +0200 [thread overview]
Message-ID: <1426872598-68807-9-git-send-email-alexander.shishkin@linux.intel.com> (raw)
In-Reply-To: <1426872598-68807-1-git-send-email-alexander.shishkin@linux.intel.com>
Software Trace Hub (STH) is a trace source device in the Intel TH
architecture, it generates data that then goes through the switch into
one or several output ports.
STH collects data from software sources using the stm device class
abstraction.
Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
drivers/hwtracing/intel_th/Kconfig | 10 ++
drivers/hwtracing/intel_th/Makefile | 3 +
drivers/hwtracing/intel_th/sth.c | 215 ++++++++++++++++++++++++++++++++++++
drivers/hwtracing/intel_th/sth.h | 37 +++++++
4 files changed, 265 insertions(+)
create mode 100644 drivers/hwtracing/intel_th/sth.c
create mode 100644 drivers/hwtracing/intel_th/sth.h
diff --git a/drivers/hwtracing/intel_th/Kconfig b/drivers/hwtracing/intel_th/Kconfig
index 4b9c577390..d21a7602cf 100644
--- a/drivers/hwtracing/intel_th/Kconfig
+++ b/drivers/hwtracing/intel_th/Kconfig
@@ -34,6 +34,16 @@ config INTEL_TH_GTH
Say Y here to enable GTH subdevice of Intel Trace Hub.
+config INTEL_TH_STH
+ tristate "Intel Trace Hub Software Trace Hub support"
+ depends on STM
+ help
+ Software Trace Hub (STH) enables trace data from software
+ trace sources to be sent out via Intel Trace Hub. It
+ uses stm class device to interface with its sources.
+
+ Say Y here to enable STH subdevice of Intel Trace Hub.
+
config INTEL_TH_DEBUG
bool "Intel Trace Hub debugging"
depends on DEBUG_FS
diff --git a/drivers/hwtracing/intel_th/Makefile b/drivers/hwtracing/intel_th/Makefile
index 8608c972a6..8c45e9fa6f 100644
--- a/drivers/hwtracing/intel_th/Makefile
+++ b/drivers/hwtracing/intel_th/Makefile
@@ -7,3 +7,6 @@ intel_th_pci-y := pci.o
obj-$(CONFIG_INTEL_TH_GTH) += intel_th_gth.o
intel_th_gth-y := gth.o
+
+obj-$(CONFIG_INTEL_TH_STH) += intel_th_sth.o
+intel_th_sth-y := sth.o
diff --git a/drivers/hwtracing/intel_th/sth.c b/drivers/hwtracing/intel_th/sth.c
new file mode 100644
index 0000000000..d3bbe06ef5
--- /dev/null
+++ b/drivers/hwtracing/intel_th/sth.c
@@ -0,0 +1,215 @@
+/*
+ * Intel Trace Hub Software Trace Hub support
+ *
+ * Copyright (C) 2014-2015 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/stm.h>
+
+#include "intel_th.h"
+#include "sth.h"
+
+struct sth_device {
+ void __iomem *base;
+ void __iomem *channels;
+ phys_addr_t channels_phys;
+ struct device *dev;
+ struct stm_data stm;
+ unsigned int sw_nmasters;
+};
+
+static struct intel_th_channel __iomem *
+sth_channel(struct sth_device *sth, unsigned int master, unsigned int channel)
+{
+ struct intel_th_channel __iomem *sw_map = sth->channels;
+
+ return &sw_map[(master - sth->stm.sw_start) * sth->stm.sw_nchannels +
+ channel];
+}
+
+static void intel_th_sw_write(struct sth_device *sth,
+ unsigned int master, unsigned int channel,
+ const unsigned char *buf, unsigned len)
+{
+ struct intel_th_channel __iomem *out =
+ sth_channel(sth, master, channel);
+ u64 __iomem *outp = &out->DnTS;
+ int i, sz;
+
+ for (i = 0; i < len; i += sz) {
+ sz = min_t(int, len - i, 4);
+ switch (sz) {
+ case 4:
+ iowrite32(*(u32 *)&buf[i], outp);
+ break;
+ case 3:
+ case 2:
+ iowrite16(*(u16 *)&buf[i], outp);
+ if (sz == 2)
+ break;
+ i += 2;
+ case 1:
+ iowrite8(*(u8 *)&buf[i], outp);
+ break;
+ }
+
+ outp = &out->Dn;
+ }
+
+ iowrite32(0, &out->FLAG);
+}
+
+static ssize_t sth_stm_write(struct stm_data *stm_data, unsigned int master,
+ unsigned int channel, const char *buf, size_t len)
+
+{
+ struct sth_device *sth = container_of(stm_data, struct sth_device, stm);
+
+ intel_th_sw_write(sth, master, channel, buf, len);
+
+ return len;
+}
+
+static phys_addr_t
+sth_stm_mmio_addr(struct stm_data *stm_data, unsigned int master,
+ unsigned int channel, unsigned int nr_chans)
+{
+ struct sth_device *sth = container_of(stm_data, struct sth_device, stm);
+ phys_addr_t addr;
+
+ master -= sth->stm.sw_start;
+ addr = sth->channels_phys + (master * sth->stm.sw_nchannels + channel) *
+ sizeof(struct intel_th_channel);
+
+ if (offset_in_page(addr) ||
+ offset_in_page(nr_chans * sizeof(struct intel_th_channel)))
+ return 0;
+
+ return addr;
+}
+
+static void sth_stm_link(struct stm_data *stm_data, unsigned int master,
+ unsigned int channel)
+{
+ struct sth_device *sth = container_of(stm_data, struct sth_device, stm);
+
+ intel_th_set_output(to_intel_th_device(sth->dev), master);
+}
+
+static int intel_th_sw_init(struct sth_device *sth)
+{
+ u32 reg;
+
+ reg = ioread32(sth->base + REG_STH_STHCAP1);
+ sth->stm.sw_nchannels = reg & 0xff;
+
+ reg = ioread32(sth->base + REG_STH_STHCAP0);
+ sth->stm.sw_start = reg & 0xffff;
+ sth->stm.sw_end = reg >> 16;
+
+ sth->sw_nmasters = sth->stm.sw_end - sth->stm.sw_start;
+ dev_dbg(sth->dev, "sw_start: %x sw_end: %x masters: %x nchannels: %x\n",
+ sth->stm.sw_start, sth->stm.sw_end, sth->sw_nmasters,
+ sth->stm.sw_nchannels);
+
+ return 0;
+}
+
+static void intel_th_sw_done(struct sth_device *sth)
+{
+}
+
+static int intel_th_sth_probe(struct intel_th_device *thdev)
+{
+ struct device *dev = &thdev->dev;
+ struct sth_device *sth;
+ struct resource *res;
+ void __iomem *base, *channels;
+ int err;
+
+ res = intel_th_device_get_resource(thdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+
+ base = devm_ioremap(dev, res->start, resource_size(res));
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ res = intel_th_device_get_resource(thdev, IORESOURCE_MEM, 1);
+ if (!res)
+ return -ENODEV;
+
+ channels = devm_ioremap(dev, res->start, resource_size(res));
+ if (IS_ERR(channels))
+ return PTR_ERR(channels);
+
+ sth = devm_kzalloc(dev, sizeof(*sth), GFP_KERNEL);
+ if (!sth)
+ return -ENOMEM;
+
+ sth->dev = dev;
+ sth->base = base;
+ sth->channels = channels;
+ sth->channels_phys = res->start;
+ sth->stm.name = dev_name(dev);
+ sth->stm.write = sth_stm_write;
+ sth->stm.mmio_addr = sth_stm_mmio_addr;
+ sth->stm.sw_mmiosz = sizeof(struct intel_th_channel);
+ sth->stm.link = sth_stm_link;
+
+ err = intel_th_sw_init(sth);
+ if (err)
+ return err;
+
+ if (stm_register_device(dev, &sth->stm, THIS_MODULE)) {
+ dev_err(dev, "stm_register_device failed\n");
+ intel_th_sw_done(sth);
+ return err;
+ }
+
+ dev_set_drvdata(dev, sth);
+
+ return 0;
+}
+
+static void intel_th_sth_remove(struct intel_th_device *thdev)
+{
+ struct sth_device *sth = dev_get_drvdata(&thdev->dev);
+
+ stm_unregister_device(&sth->stm);
+ intel_th_sw_done(sth);
+}
+
+static struct intel_th_driver intel_th_sth_driver = {
+ .probe = intel_th_sth_probe,
+ .remove = intel_th_sth_remove,
+ .driver = {
+ .name = "sth",
+ .owner = THIS_MODULE,
+ },
+};
+
+module_driver(intel_th_sth_driver,
+ intel_th_driver_register,
+ intel_th_driver_unregister);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Intel Trace Hub Software Trace Hub driver");
+MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@intel.com>");
diff --git a/drivers/hwtracing/intel_th/sth.h b/drivers/hwtracing/intel_th/sth.h
new file mode 100644
index 0000000000..5e4d913e2a
--- /dev/null
+++ b/drivers/hwtracing/intel_th/sth.h
@@ -0,0 +1,37 @@
+/*
+ * Intel Trace Hub Software Trace Hub (STH) data structures
+ *
+ * Copyright (C) 2014-2015 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef __INTEL_TH_STH_H__
+#define __INTEL_TH_STH_H__
+
+enum {
+ REG_STH_STHCAP0 = 0x0000, /* capabilities pt1 */
+ REG_STH_STHCAP1 = 0x0004, /* capabilities pt2 */
+};
+
+struct intel_th_channel {
+ u64 Dn;
+ u64 DnM;
+ u64 DnTS;
+ u64 DnMTS;
+ u64 USER;
+ u64 USER_TS;
+ u32 FLAG;
+ u32 FLAG_TS;
+ u32 MERR;
+ u32 __unused;
+} __packed;
+
+#endif /* __INTEL_TH_STH_H__ */
--
2.1.4
next prev parent reply other threads:[~2015-03-20 17:33 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-03-20 17:29 [PATCH v1 00/11] Introduce Intel Trace Hub support Alexander Shishkin
2015-03-20 17:29 ` [PATCH v1 01/11] stm class: Introduce an abstraction for System Trace Module devices Alexander Shishkin
2015-03-20 17:29 ` [PATCH v1 02/11] MAINTAINERS: add an entry for System Trace Module device class Alexander Shishkin
2015-03-20 17:29 ` [PATCH v1 03/11] stm class: dummy_stm: Add dummy driver for testing stm class Alexander Shishkin
2015-03-21 12:02 ` Paul Bolle
2015-03-22 20:38 ` Alexander Shishkin
2015-03-20 17:29 ` [PATCH v1 04/11] stm class: stm_console: Add kernel-console-over-stm driver Alexander Shishkin
2015-03-21 11:59 ` Paul Bolle
2015-03-20 17:29 ` [PATCH v1 05/11] intel_th: Add driver infrastructure for Intel Trace Hub devices Alexander Shishkin
2015-03-20 17:29 ` [PATCH v1 06/11] intel_th: Add pci glue layer for Intel Trace Hub Alexander Shishkin
2015-03-20 17:43 ` Joe Perches
2015-03-22 20:36 ` Alexander Shishkin
2015-03-20 17:29 ` [PATCH v1 07/11] intel_th: Add Global Trace Hub driver Alexander Shishkin
2015-03-20 17:59 ` Joe Perches
2015-03-22 20:35 ` Alexander Shishkin
2015-03-20 17:29 ` Alexander Shishkin [this message]
2015-03-20 17:29 ` [PATCH v1 09/11] intel_th: Add Memory Storage Unit driver Alexander Shishkin
2015-03-20 17:29 ` [PATCH v1 10/11] intel_th: Add PTI output driver Alexander Shishkin
2015-03-20 17:29 ` [PATCH v1 11/11] MAINTAINERS: add an entry for Intel(R) Trace Hub Alexander Shishkin
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=1426872598-68807-9-git-send-email-alexander.shishkin@linux.intel.com \
--to=alexander.shishkin@linux.intel.com \
--cc=gregkh@linuxfoundation.org \
--cc=keven.boell@intel.com \
--cc=laurent.fert@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mathieu.poirier@linaro.org \
--cc=norbert.schulz@intel.com \
--cc=pebolle@tiscali.nl \
--cc=peter.lachner@intel.com \
--cc=yann.fouassier@intel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox