xref: /linux/drivers/hwtracing/coresight/coresight-tpdm.h (revision c532de5a67a70f8533d495f8f2aaa9a0491c3ad0)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  */
5 
6 #ifndef _CORESIGHT_CORESIGHT_TPDM_H
7 #define _CORESIGHT_CORESIGHT_TPDM_H
8 
9 /* The max number of the datasets that TPDM supports */
10 #define TPDM_DATASETS       7
11 
12 /* CMB Subunit Registers */
13 #define TPDM_CMB_CR		(0xA00)
14 /* CMB subunit timestamp insertion enable register */
15 #define TPDM_CMB_TIER		(0xA04)
16 /* CMB subunit timestamp pattern registers */
17 #define TPDM_CMB_TPR(n)		(0xA08 + (n * 4))
18 /* CMB subunit timestamp pattern mask registers */
19 #define TPDM_CMB_TPMR(n)	(0xA10 + (n * 4))
20 /* CMB subunit trigger pattern registers */
21 #define TPDM_CMB_XPR(n)		(0xA18 + (n * 4))
22 /* CMB subunit trigger pattern mask registers */
23 #define TPDM_CMB_XPMR(n)	(0xA20 + (n * 4))
24 /* CMB MSR register */
25 #define TPDM_CMB_MSR(n)		(0xA80 + (n * 4))
26 
27 /* Enable bit for CMB subunit */
28 #define TPDM_CMB_CR_ENA		BIT(0)
29 /* Trace collection mode for CMB subunit */
30 #define TPDM_CMB_CR_MODE	BIT(1)
31 /* Timestamp control for pattern match */
32 #define TPDM_CMB_TIER_PATT_TSENAB	BIT(0)
33 /* CMB CTI timestamp request */
34 #define TPDM_CMB_TIER_XTRIG_TSENAB	BIT(1)
35 /* For timestamp fo all trace */
36 #define TPDM_CMB_TIER_TS_ALL		BIT(2)
37 
38 /* Patten register number */
39 #define TPDM_CMB_MAX_PATT		2
40 
41 /* MAX number of DSB MSR */
42 #define TPDM_CMB_MAX_MSR 32
43 
44 /* DSB Subunit Registers */
45 #define TPDM_DSB_CR		(0x780)
46 #define TPDM_DSB_TIER		(0x784)
47 #define TPDM_DSB_TPR(n)		(0x788 + (n * 4))
48 #define TPDM_DSB_TPMR(n)	(0x7A8 + (n * 4))
49 #define TPDM_DSB_XPR(n)		(0x7C8 + (n * 4))
50 #define TPDM_DSB_XPMR(n)	(0x7E8 + (n * 4))
51 #define TPDM_DSB_EDCR(n)	(0x808 + (n * 4))
52 #define TPDM_DSB_EDCMR(n)	(0x848 + (n * 4))
53 #define TPDM_DSB_MSR(n)		(0x980 + (n * 4))
54 
55 /* Enable bit for DSB subunit */
56 #define TPDM_DSB_CR_ENA		BIT(0)
57 /* Enable bit for DSB subunit perfmance mode */
58 #define TPDM_DSB_CR_MODE		BIT(1)
59 /* Enable bit for DSB subunit trigger type */
60 #define TPDM_DSB_CR_TRIG_TYPE		BIT(12)
61 /* Data bits for DSB high performace mode */
62 #define TPDM_DSB_CR_HPSEL		GENMASK(6, 2)
63 /* Data bits for DSB test mode */
64 #define TPDM_DSB_CR_TEST_MODE		GENMASK(10, 9)
65 
66 /* Enable bit for DSB subunit pattern timestamp */
67 #define TPDM_DSB_TIER_PATT_TSENAB		BIT(0)
68 /* Enable bit for DSB subunit trigger timestamp */
69 #define TPDM_DSB_TIER_XTRIG_TSENAB		BIT(1)
70 /* Bit for DSB subunit pattern type */
71 #define TPDM_DSB_TIER_PATT_TYPE			BIT(2)
72 
73 /* DSB programming modes */
74 /* DSB mode bits mask */
75 #define TPDM_DSB_MODE_MASK			GENMASK(8, 0)
76 /* Test mode control bit*/
77 #define TPDM_DSB_MODE_TEST(val)	(val & GENMASK(1, 0))
78 /* Performance mode */
79 #define TPDM_DSB_MODE_PERF		BIT(3)
80 /* High performance mode */
81 #define TPDM_DSB_MODE_HPBYTESEL(val)	(val & GENMASK(8, 4))
82 
83 #define EDCRS_PER_WORD			16
84 #define EDCR_TO_WORD_IDX(r)		((r) / EDCRS_PER_WORD)
85 #define EDCR_TO_WORD_SHIFT(r)		((r % EDCRS_PER_WORD) * 2)
86 #define EDCR_TO_WORD_VAL(val, r)	(val << EDCR_TO_WORD_SHIFT(r))
87 #define EDCR_TO_WORD_MASK(r)		EDCR_TO_WORD_VAL(0x3, r)
88 
89 #define EDCMRS_PER_WORD				32
90 #define EDCMR_TO_WORD_IDX(r)		((r) / EDCMRS_PER_WORD)
91 #define EDCMR_TO_WORD_SHIFT(r)		((r) % EDCMRS_PER_WORD)
92 
93 /* TPDM integration test registers */
94 #define TPDM_ITATBCNTRL		(0xEF0)
95 #define TPDM_ITCNTRL		(0xF00)
96 
97 /* Register value for integration test */
98 #define ATBCNTRL_VAL_32		0xC00F1409
99 #define ATBCNTRL_VAL_64		0xC01F1409
100 
101 /*
102  * Number of cycles to write value when
103  * integration test.
104  */
105 #define INTEGRATION_TEST_CYCLE	10
106 
107 /**
108  * The bits of PERIPHIDR0 register.
109  * The fields [6:0] of PERIPHIDR0 are used to determine what
110  * interfaces and subunits are present on a given TPDM.
111  *
112  * PERIPHIDR0[0] : Fix to 1 if ImplDef subunit present, else 0
113  * PERIPHIDR0[1] : Fix to 1 if DSB subunit present, else 0
114  * PERIPHIDR0[2] : Fix to 1 if CMB subunit present, else 0
115  */
116 
117 #define TPDM_PIDR0_DS_IMPDEF	BIT(0)
118 #define TPDM_PIDR0_DS_DSB	BIT(1)
119 #define TPDM_PIDR0_DS_CMB	BIT(2)
120 
121 #define TPDM_DSB_MAX_LINES	256
122 /* MAX number of EDCR registers */
123 #define TPDM_DSB_MAX_EDCR	16
124 /* MAX number of EDCMR registers */
125 #define TPDM_DSB_MAX_EDCMR	8
126 /* MAX number of DSB pattern */
127 #define TPDM_DSB_MAX_PATT	8
128 /* MAX number of DSB MSR */
129 #define TPDM_DSB_MAX_MSR 32
130 
131 #define tpdm_simple_dataset_ro(name, mem, idx)			\
132 	(&((struct tpdm_dataset_attribute[]) {			\
133 	   {								\
134 		__ATTR(name, 0444, tpdm_simple_dataset_show, NULL),	\
135 		mem,							\
136 		idx,							\
137 	   }								\
138 	})[0].attr.attr)
139 
140 #define tpdm_simple_dataset_rw(name, mem, idx)			\
141 	(&((struct tpdm_dataset_attribute[]) {			\
142 	   {								\
143 		__ATTR(name, 0644, tpdm_simple_dataset_show,		\
144 		tpdm_simple_dataset_store),		\
145 		mem,							\
146 		idx,							\
147 	   }								\
148 	})[0].attr.attr)
149 
150 #define tpdm_patt_enable_ts(name, mem)				\
151 	(&((struct tpdm_dataset_attribute[]) {			\
152 	   {							\
153 		__ATTR(name, 0644, enable_ts_show,		\
154 		enable_ts_store),		\
155 		mem,						\
156 		0,						\
157 	   }							\
158 	})[0].attr.attr)
159 
160 #define DSB_EDGE_CTRL_ATTR(nr)					\
161 		tpdm_simple_dataset_ro(edcr##nr,		\
162 		DSB_EDGE_CTRL, nr)
163 
164 #define DSB_EDGE_CTRL_MASK_ATTR(nr)				\
165 		tpdm_simple_dataset_ro(edcmr##nr,		\
166 		DSB_EDGE_CTRL_MASK, nr)
167 
168 #define DSB_TRIG_PATT_ATTR(nr)					\
169 		tpdm_simple_dataset_rw(xpr##nr,			\
170 		DSB_TRIG_PATT, nr)
171 
172 #define DSB_TRIG_PATT_MASK_ATTR(nr)				\
173 		tpdm_simple_dataset_rw(xpmr##nr,		\
174 		DSB_TRIG_PATT_MASK, nr)
175 
176 #define DSB_PATT_ATTR(nr)					\
177 		tpdm_simple_dataset_rw(tpr##nr,			\
178 		DSB_PATT, nr)
179 
180 #define DSB_PATT_MASK_ATTR(nr)					\
181 		tpdm_simple_dataset_rw(tpmr##nr,		\
182 		DSB_PATT_MASK, nr)
183 
184 #define DSB_PATT_ENABLE_TS					\
185 		tpdm_patt_enable_ts(enable_ts,			\
186 		DSB_PATT)
187 
188 #define DSB_MSR_ATTR(nr)					\
189 		tpdm_simple_dataset_rw(msr##nr,			\
190 		DSB_MSR, nr)
191 
192 #define CMB_TRIG_PATT_ATTR(nr)					\
193 		tpdm_simple_dataset_rw(xpr##nr,			\
194 		CMB_TRIG_PATT, nr)
195 
196 #define CMB_TRIG_PATT_MASK_ATTR(nr)				\
197 		tpdm_simple_dataset_rw(xpmr##nr,		\
198 		CMB_TRIG_PATT_MASK, nr)
199 
200 #define CMB_PATT_ATTR(nr)					\
201 		tpdm_simple_dataset_rw(tpr##nr,			\
202 		CMB_PATT, nr)
203 
204 #define CMB_PATT_MASK_ATTR(nr)					\
205 		tpdm_simple_dataset_rw(tpmr##nr,		\
206 		CMB_PATT_MASK, nr)
207 
208 #define CMB_PATT_ENABLE_TS					\
209 		tpdm_patt_enable_ts(enable_ts,			\
210 		CMB_PATT)
211 
212 #define CMB_MSR_ATTR(nr)					\
213 		tpdm_simple_dataset_rw(msr##nr,			\
214 		CMB_MSR, nr)
215 
216 /**
217  * struct dsb_dataset - specifics associated to dsb dataset
218  * @mode:             DSB programming mode
219  * @edge_ctrl_idx     Index number of the edge control
220  * @edge_ctrl:        Save value for edge control
221  * @edge_ctrl_mask:   Save value for edge control mask
222  * @patt_val:         Save value for pattern
223  * @patt_mask:        Save value for pattern mask
224  * @trig_patt:        Save value for trigger pattern
225  * @trig_patt_mask:   Save value for trigger pattern mask
226  * @msr               Save value for MSR
227  * @patt_ts:          Enable/Disable pattern timestamp
228  * @patt_type:        Set pattern type
229  * @trig_ts:          Enable/Disable trigger timestamp.
230  * @trig_type:        Enable/Disable trigger type.
231  */
232 struct dsb_dataset {
233 	u32			mode;
234 	u32			edge_ctrl_idx;
235 	u32			edge_ctrl[TPDM_DSB_MAX_EDCR];
236 	u32			edge_ctrl_mask[TPDM_DSB_MAX_EDCMR];
237 	u32			patt_val[TPDM_DSB_MAX_PATT];
238 	u32			patt_mask[TPDM_DSB_MAX_PATT];
239 	u32			trig_patt[TPDM_DSB_MAX_PATT];
240 	u32			trig_patt_mask[TPDM_DSB_MAX_PATT];
241 	u32			msr[TPDM_DSB_MAX_MSR];
242 	bool			patt_ts;
243 	bool			patt_type;
244 	bool			trig_ts;
245 	bool			trig_type;
246 };
247 
248 /**
249  * struct cmb_dataset
250  * @trace_mode:       Dataset collection mode
251  * @patt_val:         Save value for pattern
252  * @patt_mask:        Save value for pattern mask
253  * @trig_patt:        Save value for trigger pattern
254  * @trig_patt_mask:   Save value for trigger pattern mask
255  * @msr               Save value for MSR
256  * @patt_ts:          Indicates if pattern match for timestamp is enabled.
257  * @trig_ts:          Indicates if CTI trigger for timestamp is enabled.
258  * @ts_all:           Indicates if timestamp is enabled for all packets.
259  */
260 struct cmb_dataset {
261 	u32			trace_mode;
262 	u32			patt_val[TPDM_CMB_MAX_PATT];
263 	u32			patt_mask[TPDM_CMB_MAX_PATT];
264 	u32			trig_patt[TPDM_CMB_MAX_PATT];
265 	u32			trig_patt_mask[TPDM_CMB_MAX_PATT];
266 	u32			msr[TPDM_CMB_MAX_MSR];
267 	bool			patt_ts;
268 	bool			trig_ts;
269 	bool			ts_all;
270 };
271 
272 /**
273  * struct tpdm_drvdata - specifics associated to an TPDM component
274  * @base:       memory mapped base address for this component.
275  * @dev:        The device entity associated to this component.
276  * @csdev:      component vitals needed by the framework.
277  * @spinlock:   lock for the drvdata value.
278  * @enable:     enable status of the component.
279  * @datasets:   The datasets types present of the TPDM.
280  * @dsb         Specifics associated to TPDM DSB.
281  * @cmb         Specifics associated to TPDM CMB.
282  * @dsb_msr_num Number of MSR supported by DSB TPDM
283  * @cmb_msr_num Number of MSR supported by CMB TPDM
284  */
285 
286 struct tpdm_drvdata {
287 	void __iomem		*base;
288 	struct device		*dev;
289 	struct coresight_device	*csdev;
290 	spinlock_t		spinlock;
291 	bool			enable;
292 	unsigned long		datasets;
293 	struct dsb_dataset	*dsb;
294 	struct cmb_dataset	*cmb;
295 	u32			dsb_msr_num;
296 	u32			cmb_msr_num;
297 };
298 
299 /* Enumerate members of various datasets */
300 enum dataset_mem {
301 	DSB_EDGE_CTRL,
302 	DSB_EDGE_CTRL_MASK,
303 	DSB_TRIG_PATT,
304 	DSB_TRIG_PATT_MASK,
305 	DSB_PATT,
306 	DSB_PATT_MASK,
307 	DSB_MSR,
308 	CMB_TRIG_PATT,
309 	CMB_TRIG_PATT_MASK,
310 	CMB_PATT,
311 	CMB_PATT_MASK,
312 	CMB_MSR
313 };
314 
315 /**
316  * struct tpdm_dataset_attribute - Record the member variables and
317  * index number of datasets that need to be operated by sysfs file
318  * @attr:       The device attribute
319  * @mem:        The member in the dataset data structure
320  * @idx:        The index number of the array data
321  */
322 struct tpdm_dataset_attribute {
323 	struct device_attribute attr;
324 	enum dataset_mem mem;
325 	u32 idx;
326 };
327 
328 static bool tpdm_has_dsb_dataset(struct tpdm_drvdata *drvdata)
329 {
330 	return (drvdata->datasets & TPDM_PIDR0_DS_DSB);
331 }
332 
333 static bool tpdm_has_cmb_dataset(struct tpdm_drvdata *drvdata)
334 {
335 	return (drvdata->datasets & TPDM_PIDR0_DS_CMB);
336 }
337 #endif  /* _CORESIGHT_CORESIGHT_TPDM_H */
338