summaryrefslogtreecommitdiff
path: root/drivers/hwtracing/intel_th/intel_th.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwtracing/intel_th/intel_th.h')
-rw-r--r--drivers/hwtracing/intel_th/intel_th.h151
1 files changed, 117 insertions, 34 deletions
diff --git a/drivers/hwtracing/intel_th/intel_th.h b/drivers/hwtracing/intel_th/intel_th.h
index 3096e7054f6d..3b87cd542c1b 100644
--- a/drivers/hwtracing/intel_th/intel_th.h
+++ b/drivers/hwtracing/intel_th/intel_th.h
@@ -1,21 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Intel(R) Trace Hub 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_H__
#define __INTEL_TH_H__
+#include <linux/irqreturn.h>
+
/* intel_th_device device types */
enum {
/* Devices that generate trace data */
@@ -26,6 +20,8 @@ enum {
INTEL_TH_SWITCH,
};
+struct intel_th_device;
+
/**
* struct intel_th_output - descriptor INTEL_TH_OUTPUT type devices
* @port: output port number, assigned by the switch
@@ -33,6 +29,7 @@ enum {
* @scratchpad: scratchpad bits to flag when this output is enabled
* @multiblock: true for multiblock output configuration
* @active: true when this output is enabled
+ * @wait_empty: wait for device pipeline to be empty
*
* Output port descriptor, used by switch driver to tell which output
* port this output device corresponds to. Filled in at output device's
@@ -48,8 +45,25 @@ struct intel_th_output {
};
/**
+ * struct intel_th_drvdata - describes hardware capabilities and quirks
+ * @tscu_enable: device needs SW to enable time stamping unit
+ * @multi_is_broken: device has multiblock mode is broken
+ * @has_mintctl: device has interrupt control (MINTCTL) register
+ * @host_mode_only: device can only operate in 'host debugger' mode
+ */
+struct intel_th_drvdata {
+ unsigned int tscu_enable : 1,
+ multi_is_broken : 1,
+ has_mintctl : 1,
+ host_mode_only : 1;
+};
+
+#define INTEL_TH_CAP(_th, _cap) ((_th)->drvdata ? (_th)->drvdata->_cap : 0)
+
+/**
* struct intel_th_device - device on the intel_th bus
* @dev: device
+ * @drvdata: hardware capabilities/quirks
* @resource: array of resources available to this device
* @num_resources: number of resources in @resource array
* @type: INTEL_TH_{SOURCE,OUTPUT,SWITCH}
@@ -59,11 +73,12 @@ struct intel_th_output {
* @name: device name to match the driver
*/
struct intel_th_device {
- struct device dev;
- struct resource *resource;
- unsigned int num_resources;
- unsigned int type;
- int id;
+ struct device dev;
+ const struct intel_th_drvdata *drvdata;
+ struct resource *resource;
+ unsigned int num_resources;
+ unsigned int type;
+ int id;
/* INTEL_TH_SWITCH specific */
bool host_mode;
@@ -96,6 +111,17 @@ intel_th_device_get_resource(struct intel_th_device *thdev, unsigned int type,
return NULL;
}
+/*
+ * GTH, output ports configuration
+ */
+enum {
+ GTH_NONE = 0,
+ GTH_MSU, /* memory/usb */
+ GTH_CTP, /* Common Trace Port */
+ GTH_LPP, /* Low Power Path */
+ GTH_PTI, /* MIPI-PTI */
+};
+
/**
* intel_th_output_assigned() - if an output device is assigned to a switch port
* @thdev: the output device
@@ -106,7 +132,8 @@ static inline bool
intel_th_output_assigned(struct intel_th_device *thdev)
{
return thdev->type == INTEL_TH_OUTPUT &&
- thdev->output.port >= 0;
+ (thdev->output.port >= 0 ||
+ thdev->output.type == GTH_NONE);
}
/**
@@ -116,6 +143,7 @@ intel_th_output_assigned(struct intel_th_device *thdev)
* @remove: remove method
* @assign: match a given output type device against available outputs
* @unassign: deassociate an output type device from an output port
+ * @prepare: prepare output port for tracing
* @enable: enable tracing for a given output device
* @disable: disable tracing for a given output device
* @irq: interrupt callback
@@ -137,18 +165,23 @@ struct intel_th_driver {
struct intel_th_device *othdev);
void (*unassign)(struct intel_th_device *thdev,
struct intel_th_device *othdev);
+ void (*prepare)(struct intel_th_device *thdev,
+ struct intel_th_output *output);
void (*enable)(struct intel_th_device *thdev,
struct intel_th_output *output);
+ void (*trig_switch)(struct intel_th_device *thdev,
+ struct intel_th_output *output);
void (*disable)(struct intel_th_device *thdev,
struct intel_th_output *output);
/* output ops */
- void (*irq)(struct intel_th_device *thdev);
+ irqreturn_t (*irq)(struct intel_th_device *thdev);
+ void (*wait_empty)(struct intel_th_device *thdev);
int (*activate)(struct intel_th_device *thdev);
void (*deactivate)(struct intel_th_device *thdev);
/* file_operations for those who want a device node */
const struct file_operations *fops;
/* optional attributes */
- struct attribute_group *attr_group;
+ const struct attribute_group *attr_group;
/* source ops */
int (*set_output)(struct intel_th_device *thdev,
@@ -156,13 +189,23 @@ struct intel_th_driver {
};
#define to_intel_th_driver(_d) \
- container_of((_d), struct intel_th_driver, driver)
+ container_of_const((_d), struct intel_th_driver, driver)
#define to_intel_th_driver_or_null(_d) \
((_d) ? to_intel_th_driver(_d) : NULL)
+/*
+ * Subdevice tree structure is as follows:
+ * + struct intel_th device (pci; dev_{get,set}_drvdata()
+ * + struct intel_th_device INTEL_TH_SWITCH (GTH)
+ * + struct intel_th_device INTEL_TH_OUTPUT (MSU, PTI)
+ * + struct intel_th_device INTEL_TH_SOURCE (STH)
+ *
+ * In other words, INTEL_TH_OUTPUT devices are children of INTEL_TH_SWITCH;
+ * INTEL_TH_SWITCH and INTEL_TH_SOURCE are children of the intel_th device.
+ */
static inline struct intel_th_device *
-to_intel_th_hub(struct intel_th_device *thdev)
+to_intel_th_parent(const struct intel_th_device *thdev)
{
struct device *parent = thdev->dev.parent;
@@ -172,35 +215,58 @@ to_intel_th_hub(struct intel_th_device *thdev)
return to_intel_th_device(parent);
}
+static inline struct intel_th *to_intel_th(const struct intel_th_device *thdev)
+{
+ if (thdev->type == INTEL_TH_OUTPUT)
+ thdev = to_intel_th_parent(thdev);
+
+ if (WARN_ON_ONCE(!thdev || thdev->type == INTEL_TH_OUTPUT))
+ return NULL;
+
+ return dev_get_drvdata(thdev->dev.parent);
+}
+
struct intel_th *
-intel_th_alloc(struct device *dev, struct resource *devres,
- unsigned int ndevres, int irq);
+intel_th_alloc(struct device *dev, const struct intel_th_drvdata *drvdata,
+ struct resource *devres, unsigned int ndevres);
void intel_th_free(struct intel_th *th);
int intel_th_driver_register(struct intel_th_driver *thdrv);
void intel_th_driver_unregister(struct intel_th_driver *thdrv);
int intel_th_trace_enable(struct intel_th_device *thdev);
+int intel_th_trace_switch(struct intel_th_device *thdev);
int intel_th_trace_disable(struct intel_th_device *thdev);
int intel_th_set_output(struct intel_th_device *thdev,
unsigned int master);
+int intel_th_output_enable(struct intel_th *th, unsigned int otype);
-enum {
+enum th_mmio_idx {
TH_MMIO_CONFIG = 0,
- TH_MMIO_SW = 2,
+ TH_MMIO_SW = 1,
+ TH_MMIO_RTIT = 2,
TH_MMIO_END,
};
-#define TH_SUBDEVICE_MAX 6
#define TH_POSSIBLE_OUTPUTS 8
+/* Total number of possible subdevices: outputs + GTH + STH */
+#define TH_SUBDEVICE_MAX (TH_POSSIBLE_OUTPUTS + 2)
#define TH_CONFIGURABLE_MASTERS 256
#define TH_MSC_MAX 2
+/* Maximum IRQ vectors */
+#define TH_NVEC_MAX 8
+
/**
* struct intel_th - Intel TH controller
* @dev: driver core's device
* @thdev: subdevices
* @hub: "switch" subdevice (GTH)
+ * @resource: resources of the entire controller
+ * @num_thdevs: number of devices in the @thdev array
+ * @num_resources: number of resources in the @resource array
+ * @irq: irq number
+ * @num_irqs: number of IRQs is use
* @id: this Intel TH controller's device ID in the system
* @major: device node major for output devices
*/
@@ -209,6 +275,15 @@ struct intel_th {
struct intel_th_device *thdev[TH_SUBDEVICE_MAX];
struct intel_th_device *hub;
+ const struct intel_th_drvdata *drvdata;
+
+ struct resource resource[TH_MMIO_END];
+ int (*activate)(struct intel_th *);
+ void (*deactivate)(struct intel_th *);
+ unsigned int num_thdevs;
+ unsigned int num_resources;
+ int irq;
+ int num_irqs;
int id;
int major;
@@ -220,6 +295,17 @@ struct intel_th {
#endif
};
+static inline struct intel_th_device *
+to_intel_th_hub(struct intel_th_device *thdev)
+{
+ if (thdev->type == INTEL_TH_SWITCH)
+ return thdev;
+ else if (thdev->type == INTEL_TH_OUTPUT)
+ return to_intel_th_parent(thdev);
+
+ return to_intel_th(thdev)->hub;
+}
+
/*
* Register windows
*/
@@ -228,6 +314,13 @@ enum {
REG_GTH_OFFSET = 0x0000,
REG_GTH_LENGTH = 0x2000,
+ /* Timestamp counter unit (TSCU) */
+ REG_TSCU_OFFSET = 0x2000,
+ REG_TSCU_LENGTH = 0x1000,
+
+ REG_CTS_OFFSET = 0x3000,
+ REG_CTS_LENGTH = 0x1000,
+
/* Software Trace Hub (STH) [0x4000..0x4fff] */
REG_STH_OFFSET = 0x4000,
REG_STH_LENGTH = 0x2000,
@@ -250,16 +343,6 @@ enum {
};
/*
- * GTH, output ports configuration
- */
-enum {
- GTH_NONE = 0,
- GTH_MSU, /* memory/usb */
- GTH_CTP, /* Common Trace Port */
- GTH_PTI = 4, /* MIPI-PTI */
-};
-
-/*
* Scratchpad bits: tell firmware and external debuggers
* what we are up to.
*/