xref: /linux/drivers/hwtracing/coresight/coresight-cti.h (revision cb4eb6771c0f8fd1c52a8f6fdec7762fb087380a)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (c) 2018 Linaro Limited, All rights reserved.
4  * Author: Mike Leach <mike.leach@linaro.org>
5  */
6 
7 #ifndef _CORESIGHT_CORESIGHT_CTI_H
8 #define _CORESIGHT_CORESIGHT_CTI_H
9 
10 #include <linux/coresight.h>
11 #include <linux/device.h>
12 #include <linux/list.h>
13 #include <linux/spinlock.h>
14 #include <linux/sysfs.h>
15 #include <linux/types.h>
16 
17 #include "coresight-priv.h"
18 
19 struct fwnode_handle;
20 
21 /*
22  * Device registers
23  * 0x000 - 0x144: CTI programming and status
24  * 0xEDC - 0xEF8: CTI integration test.
25  * 0xF00 - 0xFFC: Coresight management registers.
26  */
27 /* CTI programming registers */
28 #define CTICONTROL		0x000
29 #define CTIINTACK		0x010
30 #define CTIAPPSET		0x014
31 #define CTIAPPCLEAR		0x018
32 #define CTIAPPPULSE		0x01C
33 #define CTIINEN(n)		(0x020 + (4 * n))
34 #define CTIOUTEN(n)		(0x0A0 + (4 * n))
35 #define CTITRIGINSTATUS		0x130
36 #define CTITRIGOUTSTATUS	0x134
37 #define CTICHINSTATUS		0x138
38 #define CTICHOUTSTATUS		0x13C
39 #define CTIGATE			0x140
40 #define ASICCTL			0x144
41 /* Integration test registers */
42 #define ITCHINACK		0xEDC /* WO CTI CSSoc 400 only*/
43 #define ITTRIGINACK		0xEE0 /* WO CTI CSSoc 400 only*/
44 #define ITCHOUT			0xEE4 /* WO RW-600 */
45 #define ITTRIGOUT		0xEE8 /* WO RW-600 */
46 #define ITCHOUTACK		0xEEC /* RO CTI CSSoc 400 only*/
47 #define ITTRIGOUTACK		0xEF0 /* RO CTI CSSoc 400 only*/
48 #define ITCHIN			0xEF4 /* RO */
49 #define ITTRIGIN		0xEF8 /* RO */
50 /* management registers */
51 #define CTIDEVAFF0		0xFA8
52 #define CTIDEVAFF1		0xFAC
53 
54 /*
55  * CTI CSSoc 600 has a max of 32 trigger signals per direction.
56  * CTI CSSoc 400 has 8 IO triggers - other CTIs can be impl def.
57  * Max of in and out defined in the DEVID register.
58  * - pick up actual number used from .dts parameters if present.
59  */
60 #define CTIINOUTEN_MAX		32
61 
62 /**
63  * Group of related trigger signals
64  *
65  * @nr_sigs: number of signals in the group.
66  * @used_mask: bitmask representing the signal indexes in the group.
67  * @sig_types: array of types for the signals, length nr_sigs.
68  */
69 struct cti_trig_grp {
70 	int nr_sigs;
71 	u32 used_mask;
72 	int sig_types[];
73 };
74 
75 /**
76  * Trigger connection - connection between a CTI and other (coresight) device
77  * lists input and output trigger signals for the device
78  *
79  * @con_in: connected CTIIN signals for the device.
80  * @con_out: connected CTIOUT signals for the device.
81  * @con_dev: coresight device connected to the CTI, NULL if not CS device
82  * @con_dev_name: name of connected device (CS or CPU)
83  * @node: entry node in list of connections.
84  * @con_attrs: Dynamic sysfs attributes specific to this connection.
85  * @attr_group: Dynamic attribute group created for this connection.
86  */
87 struct cti_trig_con {
88 	struct cti_trig_grp *con_in;
89 	struct cti_trig_grp *con_out;
90 	struct coresight_device *con_dev;
91 	const char *con_dev_name;
92 	struct list_head node;
93 	struct attribute **con_attrs;
94 	struct attribute_group *attr_group;
95 };
96 
97 /**
98  * struct cti_device - description of CTI device properties.
99  *
100  * @nt_trig_con: Number of external devices connected to this device.
101  * @ctm_id: which CTM this device is connected to (by default it is
102  *          assumed there is a single CTM per SoC, ID 0).
103  * @trig_cons: list of connections to this device.
104  * @cpu: CPU ID if associated with CPU, -1 otherwise.
105  * @con_groups: combined static and dynamic sysfs groups for trigger
106  *		connections.
107  */
108 struct cti_device {
109 	int nr_trig_con;
110 	u32 ctm_id;
111 	struct list_head trig_cons;
112 	int cpu;
113 	const struct attribute_group **con_groups;
114 };
115 
116 /**
117  * struct cti_config - configuration of the CTI device hardware
118  *
119  * @nr_trig_max: Max number of trigger signals implemented on device.
120  *		 (max of trig_in or trig_out) - from ID register.
121  * @nr_ctm_channels: number of available CTM channels - from ID register.
122  * @asicctl_impl: true if asicctl is implemented.
123  * @enable_req_count: CTI is enabled alongside >=1 associated devices.
124  * @trig_in_use: bitfield of in triggers registered as in use.
125  * @trig_out_use: bitfield of out triggers registered as in use.
126  * @trig_out_filter: bitfield of out triggers that are blocked if filter
127  *		     enabled. Typically this would be dbgreq / restart on
128  *		     a core CTI.
129  * @trig_filter_enable: 1 if filtering enabled.
130  * @xtrig_rchan_sel: channel selection for xtrigger connection show.
131  * @ctiappset: CTI Software application channel set.
132  * @ctiinout_sel: register selector for INEN and OUTEN regs.
133  * @ctiinen: enable input trigger to a channel.
134  * @ctiouten: enable output trigger from a channel.
135  * @ctigate: gate channel output from CTI to CTM.
136  * @asicctl: asic control register.
137  */
138 struct cti_config {
139 	/* hardware description */
140 	int nr_ctm_channels;
141 	int nr_trig_max;
142 	bool asicctl_impl;
143 
144 	/* cti enable control */
145 	int enable_req_count;
146 
147 	/* registered triggers and filtering */
148 	u32 trig_in_use;
149 	u32 trig_out_use;
150 	u32 trig_out_filter;
151 	bool trig_filter_enable;
152 	u8 xtrig_rchan_sel;
153 
154 	/* cti cross trig programmable regs */
155 	u32 ctiappset;
156 	u8 ctiinout_sel;
157 	u32 ctiinen[CTIINOUTEN_MAX];
158 	u32 ctiouten[CTIINOUTEN_MAX];
159 	u32 ctigate;
160 	u32 asicctl;
161 };
162 
163 /**
164  * struct cti_drvdata - specifics for the CTI device
165  * @base:	Memory mapped base address for this component..
166  * @csdev:	Standard CoreSight device information.
167  * @ctidev:	Extra information needed by the CTI/CTM framework.
168  * @spinlock:	Control data access to one at a time.
169  * @config:	Configuration data for this CTI device.
170  * @node:	List entry of this device in the list of CTI devices.
171  */
172 struct cti_drvdata {
173 	void __iomem *base;
174 	struct coresight_device	*csdev;
175 	struct cti_device ctidev;
176 	raw_spinlock_t spinlock;
177 	struct cti_config config;
178 	struct list_head node;
179 };
180 
181 /*
182  * Channel operation types.
183  */
184 enum cti_chan_op {
185 	CTI_CHAN_ATTACH,
186 	CTI_CHAN_DETACH,
187 };
188 
189 enum cti_trig_dir {
190 	CTI_TRIG_IN,
191 	CTI_TRIG_OUT,
192 };
193 
194 enum cti_chan_gate_op {
195 	CTI_GATE_CHAN_ENABLE,
196 	CTI_GATE_CHAN_DISABLE,
197 };
198 
199 enum cti_chan_set_op {
200 	CTI_CHAN_SET,
201 	CTI_CHAN_CLR,
202 	CTI_CHAN_PULSE,
203 };
204 
205 /* private cti driver fns & vars */
206 extern const struct attribute_group *coresight_cti_groups[];
207 int cti_add_default_connection(struct device *dev,
208 			       struct cti_drvdata *drvdata);
209 int cti_add_connection_entry(struct device *dev, struct cti_drvdata *drvdata,
210 			     struct cti_trig_con *tc,
211 			     struct coresight_device *csdev,
212 			     const char *assoc_dev_name);
213 struct cti_trig_con *cti_allocate_trig_con(struct device *dev, int in_sigs,
214 					   int out_sigs);
215 int cti_enable(struct coresight_device *csdev, enum cs_mode mode,
216 	       struct coresight_path *path);
217 int cti_disable(struct coresight_device *csdev, struct coresight_path *path);
218 void cti_write_all_hw_regs(struct cti_drvdata *drvdata);
219 void cti_write_intack(struct device *dev, u32 ackval);
220 void cti_write_single_reg(struct cti_drvdata *drvdata, int offset, u32 value);
221 u32 cti_read_single_reg(struct cti_drvdata *drvdata, int offset);
222 int cti_channel_trig_op(struct device *dev, enum cti_chan_op op,
223 			enum cti_trig_dir direction, u32 channel_idx,
224 			u32 trigger_idx);
225 int cti_channel_gate_op(struct device *dev, enum cti_chan_gate_op op,
226 			u32 channel_idx);
227 int cti_channel_setop(struct device *dev, enum cti_chan_set_op op,
228 		      u32 channel_idx);
229 int cti_create_cons_sysfs(struct device *dev, struct cti_drvdata *drvdata);
230 struct coresight_platform_data *
231 coresight_cti_get_platform_data(struct device *dev);
232 const char *cti_plat_get_node_name(struct fwnode_handle *fwnode);
233 
234 /* Check if a cti device is enabled */
cti_is_active(struct cti_config * cfg)235 static inline bool cti_is_active(struct cti_config *cfg)
236 {
237 	return !!cfg->enable_req_count;
238 }
239 
240 #endif  /* _CORESIGHT_CORESIGHT_CTI_H */
241