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