coresight.h 10.0 KB
Newer Older
1 2 3
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
4 5 6 7 8 9
 */

#ifndef _LINUX_CORESIGHT_H
#define _LINUX_CORESIGHT_H

#include <linux/device.h>
10
#include <linux/perf_event.h>
11
#include <linux/sched.h>
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42

/* Peripheral id registers (0xFD0-0xFEC) */
#define CORESIGHT_PERIPHIDR4	0xfd0
#define CORESIGHT_PERIPHIDR5	0xfd4
#define CORESIGHT_PERIPHIDR6	0xfd8
#define CORESIGHT_PERIPHIDR7	0xfdC
#define CORESIGHT_PERIPHIDR0	0xfe0
#define CORESIGHT_PERIPHIDR1	0xfe4
#define CORESIGHT_PERIPHIDR2	0xfe8
#define CORESIGHT_PERIPHIDR3	0xfeC
/* Component id registers (0xFF0-0xFFC) */
#define CORESIGHT_COMPIDR0	0xff0
#define CORESIGHT_COMPIDR1	0xff4
#define CORESIGHT_COMPIDR2	0xff8
#define CORESIGHT_COMPIDR3	0xffC

#define ETM_ARCH_V3_3		0x23
#define ETM_ARCH_V3_5		0x25
#define PFT_ARCH_V1_0		0x30
#define PFT_ARCH_V1_1		0x31

#define CORESIGHT_UNLOCK	0xc5acce55

extern struct bus_type coresight_bustype;

enum coresight_dev_type {
	CORESIGHT_DEV_TYPE_NONE,
	CORESIGHT_DEV_TYPE_SINK,
	CORESIGHT_DEV_TYPE_LINK,
	CORESIGHT_DEV_TYPE_LINKSINK,
	CORESIGHT_DEV_TYPE_SOURCE,
43
	CORESIGHT_DEV_TYPE_HELPER,
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
};

enum coresight_dev_subtype_sink {
	CORESIGHT_DEV_SUBTYPE_SINK_NONE,
	CORESIGHT_DEV_SUBTYPE_SINK_PORT,
	CORESIGHT_DEV_SUBTYPE_SINK_BUFFER,
};

enum coresight_dev_subtype_link {
	CORESIGHT_DEV_SUBTYPE_LINK_NONE,
	CORESIGHT_DEV_SUBTYPE_LINK_MERG,
	CORESIGHT_DEV_SUBTYPE_LINK_SPLIT,
	CORESIGHT_DEV_SUBTYPE_LINK_FIFO,
};

enum coresight_dev_subtype_source {
	CORESIGHT_DEV_SUBTYPE_SOURCE_NONE,
	CORESIGHT_DEV_SUBTYPE_SOURCE_PROC,
	CORESIGHT_DEV_SUBTYPE_SOURCE_BUS,
	CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE,
};

66 67
enum coresight_dev_subtype_helper {
	CORESIGHT_DEV_SUBTYPE_HELPER_NONE,
68
	CORESIGHT_DEV_SUBTYPE_HELPER_CATU,
69 70
};

71
/**
72
 * union coresight_dev_subtype - further characterisation of a type
73
 * @sink_subtype:	type of sink this component is, as defined
74
 *			by @coresight_dev_subtype_sink.
75
 * @link_subtype:	type of link this component is, as defined
76
 *			by @coresight_dev_subtype_link.
77
 * @source_subtype:	type of source this component is, as defined
78
 *			by @coresight_dev_subtype_source.
79 80
 * @helper_subtype:	type of helper this component is, as defined
 *			by @coresight_dev_subtype_helper.
81
 */
82 83 84 85 86 87
union coresight_dev_subtype {
	/* We have some devices which acts as LINK and SINK */
	struct {
		enum coresight_dev_subtype_sink sink_subtype;
		enum coresight_dev_subtype_link link_subtype;
	};
88
	enum coresight_dev_subtype_source source_subtype;
89
	enum coresight_dev_subtype_helper helper_subtype;
90 91 92 93 94 95 96 97
};

/**
 * struct coresight_platform_data - data harvested from the DT specification
 * @cpu:	the CPU a source belongs to. Only applicable for ETM/PTMs.
 * @name:	name of the component as shown under sysfs.
 * @nr_inport:	number of input ports for this component.
 * @nr_outport:	number of output ports for this component.
98
 * @conns:	Array of nr_outport connections from this component
99 100 101 102 103 104
 */
struct coresight_platform_data {
	int cpu;
	const char *name;
	int nr_inport;
	int nr_outport;
105
	struct coresight_connection *conns;
106 107 108 109 110 111 112 113 114 115
};

/**
 * struct coresight_desc - description of a component required from drivers
 * @type:	as defined by @coresight_dev_type.
 * @subtype:	as defined by @coresight_dev_subtype.
 * @ops:	generic operations for this component, as defined
		by @coresight_ops.
 * @pdata:	platform data collected from DT.
 * @dev:	The device entity associated to this component.
116
 * @groups:	operations specific to this component. These will end up
117 118 119 120
		in the component's sysfs sub-directory.
 */
struct coresight_desc {
	enum coresight_dev_type type;
121
	union coresight_dev_subtype subtype;
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
	const struct coresight_ops *ops;
	struct coresight_platform_data *pdata;
	struct device *dev;
	const struct attribute_group **groups;
};

/**
 * struct coresight_connection - representation of a single connection
 * @outport:	a connection's output port number.
 * @chid_name:	remote component's name.
 * @child_port:	remote component's port number @output is connected to.
 * @child_dev:	a @coresight_device representation of the component
		connected to @outport.
 */
struct coresight_connection {
	int outport;
	const char *child_name;
	int child_port;
	struct coresight_device *child_dev;
};

/**
 * struct coresight_device - representation of a device as used by the framework
145
 * @conns:	array of coresight_connections associated to this component.
146 147 148 149 150 151 152 153 154 155 156
 * @nr_inport:	number of input port associated to this component.
 * @nr_outport:	number of output port associated to this component.
 * @type:	as defined by @coresight_dev_type.
 * @subtype:	as defined by @coresight_dev_subtype.
 * @ops:	generic operations for this component, as defined
		by @coresight_ops.
 * @dev:	The device entity associated to this component.
 * @refcnt:	keep track of what is in use.
 * @orphan:	true if the component has connections that haven't been linked.
 * @enable:	'true' if component is currently part of an active path.
 * @activated:	'true' only if a _sink_ has been activated.  A sink can be
157 158 159
 *		activated but not yet enabled.  Enabling for a _sink_
 *		appens when a source has been selected for that it.
 * @ea:		Device attribute for sink representation under PMU directory.
160 161 162 163 164 165
 */
struct coresight_device {
	struct coresight_connection *conns;
	int nr_inport;
	int nr_outport;
	enum coresight_dev_type type;
166
	union coresight_dev_subtype subtype;
167 168 169 170 171
	const struct coresight_ops *ops;
	struct device dev;
	atomic_t *refcnt;
	bool orphan;
	bool enable;	/* true only if configured as part of a path */
172
	/* sink specific fields */
173
	bool activated;	/* true only if a sink is part of a path */
174
	struct dev_ext_attribute *ea;
175 176 177 178 179 180 181
};

#define to_coresight_device(d) container_of(d, struct coresight_device, dev)

#define source_ops(csdev)	csdev->ops->source_ops
#define sink_ops(csdev)		csdev->ops->sink_ops
#define link_ops(csdev)		csdev->ops->link_ops
182
#define helper_ops(csdev)	csdev->ops->helper_ops
183 184 185 186

/**
 * struct coresight_ops_sink - basic operations for a sink
 * Operations available for sinks
187 188 189 190 191
 * @enable:		enables the sink.
 * @disable:		disables the sink.
 * @alloc_buffer:	initialises perf's ring buffer for trace collection.
 * @free_buffer:	release memory allocated in @get_config.
 * @update_buffer:	update buffer pointers after a trace session.
192 193
 */
struct coresight_ops_sink {
194
	int (*enable)(struct coresight_device *csdev, u32 mode, void *data);
195
	void (*disable)(struct coresight_device *csdev);
196 197 198
	void *(*alloc_buffer)(struct coresight_device *csdev, int cpu,
			      void **pages, int nr_pages, bool overwrite);
	void (*free_buffer)(void *config);
199
	unsigned long (*update_buffer)(struct coresight_device *csdev,
200 201
			      struct perf_output_handle *handle,
			      void *sink_config);
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
};

/**
 * struct coresight_ops_link - basic operations for a link
 * Operations available for links.
 * @enable:	enables flow between iport and oport.
 * @disable:	disables flow between iport and oport.
 */
struct coresight_ops_link {
	int (*enable)(struct coresight_device *csdev, int iport, int oport);
	void (*disable)(struct coresight_device *csdev, int iport, int oport);
};

/**
 * struct coresight_ops_source - basic operations for a source
 * Operations available for sources.
218 219
 * @cpu_id:	returns the value of the CPU number this component
 *		is associated to.
220
 * @trace_id:	returns the value of the component's trace ID as known
221
 *		to the HW.
222
 * @enable:	enables tracing for a source.
223 224 225
 * @disable:	disables tracing for a source.
 */
struct coresight_ops_source {
226
	int (*cpu_id)(struct coresight_device *csdev);
227
	int (*trace_id)(struct coresight_device *csdev);
228
	int (*enable)(struct coresight_device *csdev,
229 230 231
		      struct perf_event *event,  u32 mode);
	void (*disable)(struct coresight_device *csdev,
			struct perf_event *event);
232 233
};

234 235 236 237 238 239 240 241 242 243 244 245 246 247
/**
 * struct coresight_ops_helper - Operations for a helper device.
 *
 * All operations could pass in a device specific data, which could
 * help the helper device to determine what to do.
 *
 * @enable	: Enable the device
 * @disable	: Disable the device
 */
struct coresight_ops_helper {
	int (*enable)(struct coresight_device *csdev, void *data);
	int (*disable)(struct coresight_device *csdev, void *data);
};

248 249 250 251
struct coresight_ops {
	const struct coresight_ops_sink *sink_ops;
	const struct coresight_ops_link *link_ops;
	const struct coresight_ops_source *source_ops;
252
	const struct coresight_ops_helper *helper_ops;
253 254 255 256 257 258 259 260 261 262
};

#ifdef CONFIG_CORESIGHT
extern struct coresight_device *
coresight_register(struct coresight_desc *desc);
extern void coresight_unregister(struct coresight_device *csdev);
extern int coresight_enable(struct coresight_device *csdev);
extern void coresight_disable(struct coresight_device *csdev);
extern int coresight_timeout(void __iomem *addr, u32 offset,
			     int position, int value);
263 264 265 266 267 268 269

extern int coresight_claim_device(void __iomem *base);
extern int coresight_claim_device_unlocked(void __iomem *base);

extern void coresight_disclaim_device(void __iomem *base);
extern void coresight_disclaim_device_unlocked(void __iomem *base);

270 271 272 273 274 275 276 277 278
#else
static inline struct coresight_device *
coresight_register(struct coresight_desc *desc) { return NULL; }
static inline void coresight_unregister(struct coresight_device *csdev) {}
static inline int
coresight_enable(struct coresight_device *csdev) { return -ENOSYS; }
static inline void coresight_disable(struct coresight_device *csdev) {}
static inline int coresight_timeout(void __iomem *addr, u32 offset,
				     int position, int value) { return 1; }
279 280 281 282 283 284 285 286 287 288 289 290 291
static inline int coresight_claim_device_unlocked(void __iomem *base)
{
	return -EINVAL;
}

static inline int coresight_claim_device(void __iomem *base)
{
	return -EINVAL;
}

static inline void coresight_disclaim_device(void __iomem *base) {}
static inline void coresight_disclaim_device_unlocked(void __iomem *base) {}

292 293
#endif

294
#ifdef CONFIG_OF
295
extern int of_coresight_get_cpu(const struct device_node *node);
296 297 298
extern struct coresight_platform_data *
of_get_coresight_platform_data(struct device *dev,
			       const struct device_node *node);
299
#else
300 301
static inline int of_coresight_get_cpu(const struct device_node *node)
{ return 0; }
302
static inline struct coresight_platform_data *of_get_coresight_platform_data(
303
	struct device *dev, const struct device_node *node) { return NULL; }
304 305 306
#endif

#endif