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 /* DSB Subunit Registers */
13 #define TPDM_DSB_CR		(0x780)
14 #define TPDM_DSB_TIER		(0x784)
15 #define TPDM_DSB_TPR(n)		(0x788 + (n * 4))
16 #define TPDM_DSB_TPMR(n)	(0x7A8 + (n * 4))
17 #define TPDM_DSB_XPR(n)		(0x7C8 + (n * 4))
18 #define TPDM_DSB_XPMR(n)	(0x7E8 + (n * 4))
19 #define TPDM_DSB_EDCR(n)	(0x808 + (n * 4))
20 #define TPDM_DSB_EDCMR(n)	(0x848 + (n * 4))
21 #define TPDM_DSB_MSR(n)		(0x980 + (n * 4))
22 
23 /* Enable bit for DSB subunit */
24 #define TPDM_DSB_CR_ENA		BIT(0)
25 /* Enable bit for DSB subunit perfmance mode */
26 #define TPDM_DSB_CR_MODE		BIT(1)
27 /* Enable bit for DSB subunit trigger type */
28 #define TPDM_DSB_CR_TRIG_TYPE		BIT(12)
29 /* Data bits for DSB high performace mode */
30 #define TPDM_DSB_CR_HPSEL		GENMASK(6, 2)
31 /* Data bits for DSB test mode */
32 #define TPDM_DSB_CR_TEST_MODE		GENMASK(10, 9)
33 
34 /* Enable bit for DSB subunit pattern timestamp */
35 #define TPDM_DSB_TIER_PATT_TSENAB		BIT(0)
36 /* Enable bit for DSB subunit trigger timestamp */
37 #define TPDM_DSB_TIER_XTRIG_TSENAB		BIT(1)
38 /* Bit for DSB subunit pattern type */
39 #define TPDM_DSB_TIER_PATT_TYPE			BIT(2)
40 
41 /* DSB programming modes */
42 /* DSB mode bits mask */
43 #define TPDM_DSB_MODE_MASK			GENMASK(8, 0)
44 /* Test mode control bit*/
45 #define TPDM_DSB_MODE_TEST(val)	(val & GENMASK(1, 0))
46 /* Performance mode */
47 #define TPDM_DSB_MODE_PERF		BIT(3)
48 /* High performance mode */
49 #define TPDM_DSB_MODE_HPBYTESEL(val)	(val & GENMASK(8, 4))
50 
51 #define EDCRS_PER_WORD			16
52 #define EDCR_TO_WORD_IDX(r)		((r) / EDCRS_PER_WORD)
53 #define EDCR_TO_WORD_SHIFT(r)		((r % EDCRS_PER_WORD) * 2)
54 #define EDCR_TO_WORD_VAL(val, r)	(val << EDCR_TO_WORD_SHIFT(r))
55 #define EDCR_TO_WORD_MASK(r)		EDCR_TO_WORD_VAL(0x3, r)
56 
57 #define EDCMRS_PER_WORD				32
58 #define EDCMR_TO_WORD_IDX(r)		((r) / EDCMRS_PER_WORD)
59 #define EDCMR_TO_WORD_SHIFT(r)		((r) % EDCMRS_PER_WORD)
60 
61 /* TPDM integration test registers */
62 #define TPDM_ITATBCNTRL		(0xEF0)
63 #define TPDM_ITCNTRL		(0xF00)
64 
65 /* Register value for integration test */
66 #define ATBCNTRL_VAL_32		0xC00F1409
67 #define ATBCNTRL_VAL_64		0xC01F1409
68 
69 /*
70  * Number of cycles to write value when
71  * integration test.
72  */
73 #define INTEGRATION_TEST_CYCLE	10
74 
75 /**
76  * The bits of PERIPHIDR0 register.
77  * The fields [6:0] of PERIPHIDR0 are used to determine what
78  * interfaces and subunits are present on a given TPDM.
79  *
80  * PERIPHIDR0[0] : Fix to 1 if ImplDef subunit present, else 0
81  * PERIPHIDR0[1] : Fix to 1 if DSB subunit present, else 0
82  */
83 
84 #define TPDM_PIDR0_DS_IMPDEF	BIT(0)
85 #define TPDM_PIDR0_DS_DSB	BIT(1)
86 
87 #define TPDM_DSB_MAX_LINES	256
88 /* MAX number of EDCR registers */
89 #define TPDM_DSB_MAX_EDCR	16
90 /* MAX number of EDCMR registers */
91 #define TPDM_DSB_MAX_EDCMR	8
92 /* MAX number of DSB pattern */
93 #define TPDM_DSB_MAX_PATT	8
94 /* MAX number of DSB MSR */
95 #define TPDM_DSB_MAX_MSR 32
96 
97 #define tpdm_simple_dataset_ro(name, mem, idx)			\
98 	(&((struct tpdm_dataset_attribute[]) {			\
99 	   {								\
100 		__ATTR(name, 0444, tpdm_simple_dataset_show, NULL),	\
101 		mem,							\
102 		idx,							\
103 	   }								\
104 	})[0].attr.attr)
105 
106 #define tpdm_simple_dataset_rw(name, mem, idx)			\
107 	(&((struct tpdm_dataset_attribute[]) {			\
108 	   {								\
109 		__ATTR(name, 0644, tpdm_simple_dataset_show,		\
110 		tpdm_simple_dataset_store),		\
111 		mem,							\
112 		idx,							\
113 	   }								\
114 	})[0].attr.attr)
115 
116 #define DSB_EDGE_CTRL_ATTR(nr)					\
117 		tpdm_simple_dataset_ro(edcr##nr,		\
118 		DSB_EDGE_CTRL, nr)
119 
120 #define DSB_EDGE_CTRL_MASK_ATTR(nr)				\
121 		tpdm_simple_dataset_ro(edcmr##nr,		\
122 		DSB_EDGE_CTRL_MASK, nr)
123 
124 #define DSB_TRIG_PATT_ATTR(nr)					\
125 		tpdm_simple_dataset_rw(xpr##nr,			\
126 		DSB_TRIG_PATT, nr)
127 
128 #define DSB_TRIG_PATT_MASK_ATTR(nr)				\
129 		tpdm_simple_dataset_rw(xpmr##nr,		\
130 		DSB_TRIG_PATT_MASK, nr)
131 
132 #define DSB_PATT_ATTR(nr)					\
133 		tpdm_simple_dataset_rw(tpr##nr,			\
134 		DSB_PATT, nr)
135 
136 #define DSB_PATT_MASK_ATTR(nr)					\
137 		tpdm_simple_dataset_rw(tpmr##nr,		\
138 		DSB_PATT_MASK, nr)
139 
140 #define DSB_MSR_ATTR(nr)					\
141 		tpdm_simple_dataset_rw(msr##nr,			\
142 		DSB_MSR, nr)
143 
144 /**
145  * struct dsb_dataset - specifics associated to dsb dataset
146  * @mode:             DSB programming mode
147  * @edge_ctrl_idx     Index number of the edge control
148  * @edge_ctrl:        Save value for edge control
149  * @edge_ctrl_mask:   Save value for edge control mask
150  * @patt_val:         Save value for pattern
151  * @patt_mask:        Save value for pattern mask
152  * @trig_patt:        Save value for trigger pattern
153  * @trig_patt_mask:   Save value for trigger pattern mask
154  * @msr               Save value for MSR
155  * @patt_ts:          Enable/Disable pattern timestamp
156  * @patt_type:        Set pattern type
157  * @trig_ts:          Enable/Disable trigger timestamp.
158  * @trig_type:        Enable/Disable trigger type.
159  */
160 struct dsb_dataset {
161 	u32			mode;
162 	u32			edge_ctrl_idx;
163 	u32			edge_ctrl[TPDM_DSB_MAX_EDCR];
164 	u32			edge_ctrl_mask[TPDM_DSB_MAX_EDCMR];
165 	u32			patt_val[TPDM_DSB_MAX_PATT];
166 	u32			patt_mask[TPDM_DSB_MAX_PATT];
167 	u32			trig_patt[TPDM_DSB_MAX_PATT];
168 	u32			trig_patt_mask[TPDM_DSB_MAX_PATT];
169 	u32			msr[TPDM_DSB_MAX_MSR];
170 	bool			patt_ts;
171 	bool			patt_type;
172 	bool			trig_ts;
173 	bool			trig_type;
174 };
175 
176 /**
177  * struct tpdm_drvdata - specifics associated to an TPDM component
178  * @base:       memory mapped base address for this component.
179  * @dev:        The device entity associated to this component.
180  * @csdev:      component vitals needed by the framework.
181  * @spinlock:   lock for the drvdata value.
182  * @enable:     enable status of the component.
183  * @datasets:   The datasets types present of the TPDM.
184  * @dsb         Specifics associated to TPDM DSB.
185  * @dsb_msr_num Number of MSR supported by DSB TPDM
186  */
187 
188 struct tpdm_drvdata {
189 	void __iomem		*base;
190 	struct device		*dev;
191 	struct coresight_device	*csdev;
192 	spinlock_t		spinlock;
193 	bool			enable;
194 	unsigned long		datasets;
195 	struct dsb_dataset	*dsb;
196 	u32			dsb_msr_num;
197 };
198 
199 /* Enumerate members of various datasets */
200 enum dataset_mem {
201 	DSB_EDGE_CTRL,
202 	DSB_EDGE_CTRL_MASK,
203 	DSB_TRIG_PATT,
204 	DSB_TRIG_PATT_MASK,
205 	DSB_PATT,
206 	DSB_PATT_MASK,
207 	DSB_MSR,
208 };
209 
210 /**
211  * struct tpdm_dataset_attribute - Record the member variables and
212  * index number of datasets that need to be operated by sysfs file
213  * @attr:       The device attribute
214  * @mem:        The member in the dataset data structure
215  * @idx:        The index number of the array data
216  */
217 struct tpdm_dataset_attribute {
218 	struct device_attribute attr;
219 	enum dataset_mem mem;
220 	u32 idx;
221 };
222 
223 #endif  /* _CORESIGHT_CORESIGHT_TPDM_H */
224