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 */
232struct 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 */
260struct 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
286struct 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 */
300enum 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 */
322struct tpdm_dataset_attribute {
323	struct device_attribute attr;
324	enum dataset_mem mem;
325	u32 idx;
326};
327
328static bool tpdm_has_dsb_dataset(struct tpdm_drvdata *drvdata)
329{
330	return (drvdata->datasets & TPDM_PIDR0_DS_DSB);
331}
332
333static 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