summaryrefslogtreecommitdiff
path: root/drivers/hwtracing/coresight/coresight-cti.h
blob: 8b106b13a244441f92d3d449e072cc26c5e3d7d6 (plain)
1
2
3
4
5
6
7
8
9
10
11
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2018 Linaro Limited, All rights reserved.
 * Author: Mike Leach <mike.leach@linaro.org>
 */

#ifndef _CORESIGHT_CORESIGHT_CTI_H
#define _CORESIGHT_CORESIGHT_CTI_H

#include <linux/coresight.h>
#include <linux/device.h>
#include <linux/fwnode.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/sysfs.h>
#include <linux/types.h>

#include "coresight-priv.h"

/*
 * Device registers
 * 0x000 - 0x144: CTI programming and status
 * 0xEDC - 0xEF8: CTI integration test.
 * 0xF00 - 0xFFC: Coresight management registers.
 */
/* CTI programming registers */
#define CTICONTROL		0x000
#define CTIINTACK		0x010
#define CTIAPPSET		0x014
#define CTIAPPCLEAR		0x018
#define CTIAPPPULSE		0x01C
#define CTIINEN(n)		(0x020 + (4 * n))
#define CTIOUTEN(n)		(0x0A0 + (4 * n))
#define CTITRIGINSTATUS		0x130
#define CTITRIGOUTSTATUS	0x134
#define CTICHINSTATUS		0x138
#define CTICHOUTSTATUS		0x13C
#define CTIGATE			0x140
#define ASICCTL			0x144
/* Integration test registers */
#define ITCHINACK		0xEDC /* WO CTI CSSoc 400 only*/
#define ITTRIGINACK		0xEE0 /* WO CTI CSSoc 400 only*/
#define ITCHOUT			0xEE4 /* WO RW-600 */
#define ITTRIGOUT		0xEE8 /* WO RW-600 */
#define ITCHOUTACK		0xEEC /* RO CTI CSSoc 400 only*/
#define ITTRIGOUTACK		0xEF0 /* RO CTI CSSoc 400 only*/
#define ITCHIN			0xEF4 /* RO */
#define ITTRIGIN		0xEF8 /* RO */
/* management registers */
#define CTIDEVAFF0		0xFA8
#define CTIDEVAFF1		0xFAC

/*
 * CTI CSSoc 600 has a max of 32 trigger signals per direction.
 * CTI CSSoc 400 has 8 IO triggers - other CTIs can be impl def.
 * Max of in and out defined in the DEVID register.
 * - pick up actual number used from .dts parameters if present.
 */
#define CTIINOUTEN_MAX		32

/**
 * Group of related trigger signals
 *
 * @nr_sigs: number of signals in the group.
 * @used_mask: bitmask representing the signal indexes in the group.
 * @sig_types: array of types for the signals, length nr_sigs.
 */
struct cti_trig_grp {
	int nr_sigs;
	u32 used_mask;
	int sig_types[];
};

/**
 * Trigger connection - connection between a CTI and other (coresight) device
 * lists input and output trigger signals for the device
 *
 * @con_in: connected CTIIN signals for the device.
 * @con_out: connected CTIOUT signals for the device.
 * @con_dev: coresight device connected to the CTI, NULL if not CS device
 * @con_dev_name: name of connected device (CS or CPU)
 * @node: entry node in list of connections.
 * @con_attrs: Dynamic sysfs attributes specific to this connection.
 * @attr_group: Dynamic attribute group created for this connection.
 */
struct cti_trig_con {
	struct cti_trig_grp *con_in;
	struct cti_trig_grp *con_out;
	struct coresight_device *con_dev;
	const char *con_dev_name;
	struct list_head node;
	struct attribute **con_attrs;
	struct attribute_group *attr_group;
};

/**
 * struct cti_device - description of CTI device properties.
 *
 * @nt_trig_con: Number of external devices connected to this device.
 * @ctm_id: which CTM this device is connected to (by default it is
 *          assumed there is a single CTM per SoC, ID 0).
 * @trig_cons: list of connections to this device.
 * @cpu: CPU ID if associated with CPU, -1 otherwise.
 * @con_groups: combined static and dynamic sysfs groups for trigger
 *		connections.
 */
struct cti_device {
	int nr_trig_con;
	u32 ctm_id;
	struct list_head trig_cons;
	int cpu;
	const struct attribute_group **con_groups;
};

/**
 * struct cti_config - configuration of the CTI device hardware
 *
 * @nr_trig_max: Max number of trigger signals implemented on device.
 *		 (max of trig_in or trig_out) - from ID register.
 * @nr_ctm_channels: number of available CTM channels - from ID register.
 * @enable_req_count: CTI is enabled alongside >=1 associated devices.
 * @hw_enabled: true if hw is currently enabled.
 * @hw_powered: true if associated cpu powered on, or no cpu.
 * @trig_in_use: bitfield of in triggers registered as in use.
 * @trig_out_use: bitfield of out triggers registered as in use.
 * @trig_out_filter: bitfield of out triggers that are blocked if filter
 *		     enabled. Typically this would be dbgreq / restart on
 *		     a core CTI.
 * @trig_filter_enable: 1 if filtering enabled.
 * @xtrig_rchan_sel: channel selection for xtrigger connection show.
 * @ctiappset: CTI Software application channel set.
 * @ctiinout_sel: register selector for INEN and OUTEN regs.
 * @ctiinen: enable input trigger to a channel.
 * @ctiouten: enable output trigger from a channel.
 * @ctigate: gate channel output from CTI to CTM.
 * @asicctl: asic control register.
 */
struct cti_config {
	/* hardware description */
	int nr_ctm_channels;
	int nr_trig_max;

	/* cti enable control */
	int enable_req_count;
	bool hw_enabled;
	bool hw_powered;

	/* registered triggers and filtering */
	u32 trig_in_use;
	u32 trig_out_use;
	u32 trig_out_filter;
	bool trig_filter_enable;
	u8 xtrig_rchan_sel;

	/* cti cross trig programmable regs */
	u32 ctiappset;
	u8 ctiinout_sel;
	u32 ctiinen[CTIINOUTEN_MAX];
	u32 ctiouten[CTIINOUTEN_MAX];
	u32 ctigate;
	u32 asicctl;
};

/**
 * struct cti_drvdata - specifics for the CTI device
 * @base:	Memory mapped base address for this component..
 * @csdev:	Standard CoreSight device information.
 * @ctidev:	Extra information needed by the CTI/CTM framework.
 * @spinlock:	Control data access to one at a time.
 * @config:	Configuration data for this CTI device.
 * @node:	List entry of this device in the list of CTI devices.
 * @csdev_release: release function for underlying coresight_device.
 */
struct cti_drvdata {
	void __iomem *base;
	struct coresight_device	*csdev;
	struct cti_device ctidev;
	spinlock_t spinlock;
	struct cti_config config;
	struct list_head node;
	void (*csdev_release)(struct device *dev);
};

/*
 * Channel operation types.
 */
enum cti_chan_op {
	CTI_CHAN_ATTACH,
	CTI_CHAN_DETACH,
};

enum cti_trig_dir {
	CTI_TRIG_IN,
	CTI_TRIG_OUT,
};

enum cti_chan_gate_op {
	CTI_GATE_CHAN_ENABLE,
	CTI_GATE_CHAN_DISABLE,
};

enum cti_chan_set_op {
	CTI_CHAN_SET,
	CTI_CHAN_CLR,
	CTI_CHAN_PULSE,
};

/* private cti driver fns & vars */
extern const struct attribute_group *coresight_cti_groups[];
int cti_add_default_connection(struct device *dev,
			       struct cti_drvdata *drvdata);
int cti_add_connection_entry(struct device *dev, struct cti_drvdata *drvdata,
			     struct cti_trig_con *tc,
			     struct coresight_device *csdev,
			     const char *assoc_dev_name);
struct cti_trig_con *cti_allocate_trig_con(struct device *dev, int in_sigs,
					   int out_sigs);
int cti_enable(struct coresight_device *csdev);
int cti_disable(struct coresight_device *csdev);
void cti_write_all_hw_regs(struct cti_drvdata *drvdata);
void cti_write_intack(struct device *dev, u32 ackval);
void cti_write_single_reg(struct cti_drvdata *drvdata, int offset, u32 value);
int cti_channel_trig_op(struct device *dev, enum cti_chan_op op,
			enum cti_trig_dir direction, u32 channel_idx,
			u32 trigger_idx);
int cti_channel_gate_op(struct device *dev, enum cti_chan_gate_op op,
			u32 channel_idx);
int cti_channel_setop(struct device *dev, enum cti_chan_set_op op,
		      u32 channel_idx);
int cti_create_cons_sysfs(struct device *dev, struct cti_drvdata *drvdata);
struct coresight_platform_data *
coresight_cti_get_platform_data(struct device *dev);
const char *cti_plat_get_node_name(struct fwnode_handle *fwnode);

/* cti powered and enabled */
static inline bool cti_active(struct cti_config *cfg)
{
	return cfg->hw_powered && cfg->hw_enabled;
}

#endif  /* _CORESIGHT_CORESIGHT_CTI_H */