summaryrefslogtreecommitdiff
path: root/drivers/hwtracing/coresight/coresight-tpdm.h
blob: e08d212642e351a3797d54f5d56c3b2196c9a23d (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
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
 */

#ifndef _CORESIGHT_CORESIGHT_TPDM_H
#define _CORESIGHT_CORESIGHT_TPDM_H

/* The max number of the datasets that TPDM supports */
#define TPDM_DATASETS       7

/* CMB Subunit Registers */
#define TPDM_CMB_CR		(0xA00)
/* CMB subunit timestamp insertion enable register */
#define TPDM_CMB_TIER		(0xA04)
/* CMB subunit timestamp pattern registers */
#define TPDM_CMB_TPR(n)		(0xA08 + (n * 4))
/* CMB subunit timestamp pattern mask registers */
#define TPDM_CMB_TPMR(n)	(0xA10 + (n * 4))
/* CMB subunit trigger pattern registers */
#define TPDM_CMB_XPR(n)		(0xA18 + (n * 4))
/* CMB subunit trigger pattern mask registers */
#define TPDM_CMB_XPMR(n)	(0xA20 + (n * 4))
/* CMB MSR register */
#define TPDM_CMB_MSR(n)		(0xA80 + (n * 4))

/* Enable bit for CMB subunit */
#define TPDM_CMB_CR_ENA		BIT(0)
/* Trace collection mode for CMB subunit */
#define TPDM_CMB_CR_MODE	BIT(1)
/* Timestamp control for pattern match */
#define TPDM_CMB_TIER_PATT_TSENAB	BIT(0)
/* CMB CTI timestamp request */
#define TPDM_CMB_TIER_XTRIG_TSENAB	BIT(1)
/* For timestamp fo all trace */
#define TPDM_CMB_TIER_TS_ALL		BIT(2)

/* Patten register number */
#define TPDM_CMB_MAX_PATT		2

/* MAX number of DSB MSR */
#define TPDM_CMB_MAX_MSR 32

/* DSB Subunit Registers */
#define TPDM_DSB_CR		(0x780)
#define TPDM_DSB_TIER		(0x784)
#define TPDM_DSB_TPR(n)		(0x788 + (n * 4))
#define TPDM_DSB_TPMR(n)	(0x7A8 + (n * 4))
#define TPDM_DSB_XPR(n)		(0x7C8 + (n * 4))
#define TPDM_DSB_XPMR(n)	(0x7E8 + (n * 4))
#define TPDM_DSB_EDCR(n)	(0x808 + (n * 4))
#define TPDM_DSB_EDCMR(n)	(0x848 + (n * 4))
#define TPDM_DSB_MSR(n)		(0x980 + (n * 4))

/* Enable bit for DSB subunit */
#define TPDM_DSB_CR_ENA		BIT(0)
/* Enable bit for DSB subunit perfmance mode */
#define TPDM_DSB_CR_MODE		BIT(1)
/* Enable bit for DSB subunit trigger type */
#define TPDM_DSB_CR_TRIG_TYPE		BIT(12)
/* Data bits for DSB high performace mode */
#define TPDM_DSB_CR_HPSEL		GENMASK(6, 2)
/* Data bits for DSB test mode */
#define TPDM_DSB_CR_TEST_MODE		GENMASK(10, 9)

/* Enable bit for DSB subunit pattern timestamp */
#define TPDM_DSB_TIER_PATT_TSENAB		BIT(0)
/* Enable bit for DSB subunit trigger timestamp */
#define TPDM_DSB_TIER_XTRIG_TSENAB		BIT(1)
/* Bit for DSB subunit pattern type */
#define TPDM_DSB_TIER_PATT_TYPE			BIT(2)

/* DSB programming modes */
/* DSB mode bits mask */
#define TPDM_DSB_MODE_MASK			GENMASK(8, 0)
/* Test mode control bit*/
#define TPDM_DSB_MODE_TEST(val)	(val & GENMASK(1, 0))
/* Performance mode */
#define TPDM_DSB_MODE_PERF		BIT(3)
/* High performance mode */
#define TPDM_DSB_MODE_HPBYTESEL(val)	(val & GENMASK(8, 4))

#define EDCRS_PER_WORD			16
#define EDCR_TO_WORD_IDX(r)		((r) / EDCRS_PER_WORD)
#define EDCR_TO_WORD_SHIFT(r)		((r % EDCRS_PER_WORD) * 2)
#define EDCR_TO_WORD_VAL(val, r)	(val << EDCR_TO_WORD_SHIFT(r))
#define EDCR_TO_WORD_MASK(r)		EDCR_TO_WORD_VAL(0x3, r)

#define EDCMRS_PER_WORD				32
#define EDCMR_TO_WORD_IDX(r)		((r) / EDCMRS_PER_WORD)
#define EDCMR_TO_WORD_SHIFT(r)		((r) % EDCMRS_PER_WORD)

/* TPDM integration test registers */
#define TPDM_ITATBCNTRL		(0xEF0)
#define TPDM_ITCNTRL		(0xF00)

/* Register value for integration test */
#define ATBCNTRL_VAL_32		0xC00F1409
#define ATBCNTRL_VAL_64		0xC01F1409

/*
 * Number of cycles to write value when
 * integration test.
 */
#define INTEGRATION_TEST_CYCLE	10

/**
 * The bits of PERIPHIDR0 register.
 * The fields [6:0] of PERIPHIDR0 are used to determine what
 * interfaces and subunits are present on a given TPDM.
 *
 * PERIPHIDR0[0] : Fix to 1 if ImplDef subunit present, else 0
 * PERIPHIDR0[1] : Fix to 1 if DSB subunit present, else 0
 * PERIPHIDR0[2] : Fix to 1 if CMB subunit present, else 0
 */

#define TPDM_PIDR0_DS_IMPDEF	BIT(0)
#define TPDM_PIDR0_DS_DSB	BIT(1)
#define TPDM_PIDR0_DS_CMB	BIT(2)

#define TPDM_DSB_MAX_LINES	256
/* MAX number of EDCR registers */
#define TPDM_DSB_MAX_EDCR	16
/* MAX number of EDCMR registers */
#define TPDM_DSB_MAX_EDCMR	8
/* MAX number of DSB pattern */
#define TPDM_DSB_MAX_PATT	8
/* MAX number of DSB MSR */
#define TPDM_DSB_MAX_MSR 32

#define tpdm_simple_dataset_ro(name, mem, idx)			\
	(&((struct tpdm_dataset_attribute[]) {			\
	   {								\
		__ATTR(name, 0444, tpdm_simple_dataset_show, NULL),	\
		mem,							\
		idx,							\
	   }								\
	})[0].attr.attr)

#define tpdm_simple_dataset_rw(name, mem, idx)			\
	(&((struct tpdm_dataset_attribute[]) {			\
	   {								\
		__ATTR(name, 0644, tpdm_simple_dataset_show,		\
		tpdm_simple_dataset_store),		\
		mem,							\
		idx,							\
	   }								\
	})[0].attr.attr)

#define tpdm_patt_enable_ts(name, mem)				\
	(&((struct tpdm_dataset_attribute[]) {			\
	   {							\
		__ATTR(name, 0644, enable_ts_show,		\
		enable_ts_store),		\
		mem,						\
		0,						\
	   }							\
	})[0].attr.attr)

#define DSB_EDGE_CTRL_ATTR(nr)					\
		tpdm_simple_dataset_ro(edcr##nr,		\
		DSB_EDGE_CTRL, nr)

#define DSB_EDGE_CTRL_MASK_ATTR(nr)				\
		tpdm_simple_dataset_ro(edcmr##nr,		\
		DSB_EDGE_CTRL_MASK, nr)

#define DSB_TRIG_PATT_ATTR(nr)					\
		tpdm_simple_dataset_rw(xpr##nr,			\
		DSB_TRIG_PATT, nr)

#define DSB_TRIG_PATT_MASK_ATTR(nr)				\
		tpdm_simple_dataset_rw(xpmr##nr,		\
		DSB_TRIG_PATT_MASK, nr)

#define DSB_PATT_ATTR(nr)					\
		tpdm_simple_dataset_rw(tpr##nr,			\
		DSB_PATT, nr)

#define DSB_PATT_MASK_ATTR(nr)					\
		tpdm_simple_dataset_rw(tpmr##nr,		\
		DSB_PATT_MASK, nr)

#define DSB_PATT_ENABLE_TS					\
		tpdm_patt_enable_ts(enable_ts,			\
		DSB_PATT)

#define DSB_MSR_ATTR(nr)					\
		tpdm_simple_dataset_rw(msr##nr,			\
		DSB_MSR, nr)

#define CMB_TRIG_PATT_ATTR(nr)					\
		tpdm_simple_dataset_rw(xpr##nr,			\
		CMB_TRIG_PATT, nr)

#define CMB_TRIG_PATT_MASK_ATTR(nr)				\
		tpdm_simple_dataset_rw(xpmr##nr,		\
		CMB_TRIG_PATT_MASK, nr)

#define CMB_PATT_ATTR(nr)					\
		tpdm_simple_dataset_rw(tpr##nr,			\
		CMB_PATT, nr)

#define CMB_PATT_MASK_ATTR(nr)					\
		tpdm_simple_dataset_rw(tpmr##nr,		\
		CMB_PATT_MASK, nr)

#define CMB_PATT_ENABLE_TS					\
		tpdm_patt_enable_ts(enable_ts,			\
		CMB_PATT)

#define CMB_MSR_ATTR(nr)					\
		tpdm_simple_dataset_rw(msr##nr,			\
		CMB_MSR, nr)

/**
 * struct dsb_dataset - specifics associated to dsb dataset
 * @mode:             DSB programming mode
 * @edge_ctrl_idx     Index number of the edge control
 * @edge_ctrl:        Save value for edge control
 * @edge_ctrl_mask:   Save value for edge control mask
 * @patt_val:         Save value for pattern
 * @patt_mask:        Save value for pattern mask
 * @trig_patt:        Save value for trigger pattern
 * @trig_patt_mask:   Save value for trigger pattern mask
 * @msr               Save value for MSR
 * @patt_ts:          Enable/Disable pattern timestamp
 * @patt_type:        Set pattern type
 * @trig_ts:          Enable/Disable trigger timestamp.
 * @trig_type:        Enable/Disable trigger type.
 */
struct dsb_dataset {
	u32			mode;
	u32			edge_ctrl_idx;
	u32			edge_ctrl[TPDM_DSB_MAX_EDCR];
	u32			edge_ctrl_mask[TPDM_DSB_MAX_EDCMR];
	u32			patt_val[TPDM_DSB_MAX_PATT];
	u32			patt_mask[TPDM_DSB_MAX_PATT];
	u32			trig_patt[TPDM_DSB_MAX_PATT];
	u32			trig_patt_mask[TPDM_DSB_MAX_PATT];
	u32			msr[TPDM_DSB_MAX_MSR];
	bool			patt_ts;
	bool			patt_type;
	bool			trig_ts;
	bool			trig_type;
};

/**
 * struct cmb_dataset
 * @trace_mode:       Dataset collection mode
 * @patt_val:         Save value for pattern
 * @patt_mask:        Save value for pattern mask
 * @trig_patt:        Save value for trigger pattern
 * @trig_patt_mask:   Save value for trigger pattern mask
 * @msr               Save value for MSR
 * @patt_ts:          Indicates if pattern match for timestamp is enabled.
 * @trig_ts:          Indicates if CTI trigger for timestamp is enabled.
 * @ts_all:           Indicates if timestamp is enabled for all packets.
 */
struct cmb_dataset {
	u32			trace_mode;
	u32			patt_val[TPDM_CMB_MAX_PATT];
	u32			patt_mask[TPDM_CMB_MAX_PATT];
	u32			trig_patt[TPDM_CMB_MAX_PATT];
	u32			trig_patt_mask[TPDM_CMB_MAX_PATT];
	u32			msr[TPDM_CMB_MAX_MSR];
	bool			patt_ts;
	bool			trig_ts;
	bool			ts_all;
};

/**
 * struct tpdm_drvdata - specifics associated to an TPDM component
 * @base:       memory mapped base address for this component.
 * @dev:        The device entity associated to this component.
 * @csdev:      component vitals needed by the framework.
 * @spinlock:   lock for the drvdata value.
 * @enable:     enable status of the component.
 * @datasets:   The datasets types present of the TPDM.
 * @dsb         Specifics associated to TPDM DSB.
 * @cmb         Specifics associated to TPDM CMB.
 * @dsb_msr_num Number of MSR supported by DSB TPDM
 * @cmb_msr_num Number of MSR supported by CMB TPDM
 */

struct tpdm_drvdata {
	void __iomem		*base;
	struct device		*dev;
	struct coresight_device	*csdev;
	spinlock_t		spinlock;
	bool			enable;
	unsigned long		datasets;
	struct dsb_dataset	*dsb;
	struct cmb_dataset	*cmb;
	u32			dsb_msr_num;
	u32			cmb_msr_num;
};

/* Enumerate members of various datasets */
enum dataset_mem {
	DSB_EDGE_CTRL,
	DSB_EDGE_CTRL_MASK,
	DSB_TRIG_PATT,
	DSB_TRIG_PATT_MASK,
	DSB_PATT,
	DSB_PATT_MASK,
	DSB_MSR,
	CMB_TRIG_PATT,
	CMB_TRIG_PATT_MASK,
	CMB_PATT,
	CMB_PATT_MASK,
	CMB_MSR
};

/**
 * struct tpdm_dataset_attribute - Record the member variables and
 * index number of datasets that need to be operated by sysfs file
 * @attr:       The device attribute
 * @mem:        The member in the dataset data structure
 * @idx:        The index number of the array data
 */
struct tpdm_dataset_attribute {
	struct device_attribute attr;
	enum dataset_mem mem;
	u32 idx;
};

static bool tpdm_has_dsb_dataset(struct tpdm_drvdata *drvdata)
{
	return (drvdata->datasets & TPDM_PIDR0_DS_DSB);
}

static bool tpdm_has_cmb_dataset(struct tpdm_drvdata *drvdata)
{
	return (drvdata->datasets & TPDM_PIDR0_DS_CMB);
}
#endif  /* _CORESIGHT_CORESIGHT_TPDM_H */