blob: d792d4eebbaccee015adc181f3b180b4c9bb2b47 [file] [log] [blame]
Shrenuj Bansala419c792016-10-20 14:05:11 -07001/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/platform_device.h>
14#include <linux/coresight.h>
15
16#include "adreno.h"
17
18#define TO_ADRENO_CORESIGHT_ATTR(_attr) \
19 container_of(_attr, struct adreno_coresight_attr, attr)
20
21ssize_t adreno_coresight_show_register(struct device *dev,
22 struct device_attribute *attr, char *buf)
23{
24 unsigned int val = 0;
25 struct kgsl_device *device = dev_get_drvdata(dev->parent);
26 struct adreno_device *adreno_dev;
27 struct adreno_coresight_attr *cattr = TO_ADRENO_CORESIGHT_ATTR(attr);
28
29 if (device == NULL)
30 return -EINVAL;
31
32 adreno_dev = ADRENO_DEVICE(device);
33
34 if (cattr->reg == NULL)
35 return -EINVAL;
36
37 /*
38 * Return the current value of the register if coresight is enabled,
39 * otherwise report 0
40 */
41
42 mutex_lock(&device->mutex);
43 if (test_bit(ADRENO_DEVICE_CORESIGHT, &adreno_dev->priv)) {
44
45 /*
46 * If the device isn't power collapsed read the actual value
47 * from the hardware - otherwise return the cached value
48 */
49
50 if (device->state == KGSL_STATE_ACTIVE ||
51 device->state == KGSL_STATE_NAP) {
52 if (!kgsl_active_count_get(device)) {
53 kgsl_regread(device, cattr->reg->offset,
54 &cattr->reg->value);
55 kgsl_active_count_put(device);
56 }
57 }
58
59 val = cattr->reg->value;
60 }
61 mutex_unlock(&device->mutex);
62
63 return snprintf(buf, PAGE_SIZE, "0x%X\n", val);
64}
65
66ssize_t adreno_coresight_store_register(struct device *dev,
67 struct device_attribute *attr, const char *buf, size_t size)
68{
69 struct kgsl_device *device = dev_get_drvdata(dev->parent);
70 struct adreno_device *adreno_dev;
71 struct adreno_coresight_attr *cattr = TO_ADRENO_CORESIGHT_ATTR(attr);
72 unsigned long val;
73 int ret;
74
75 if (device == NULL)
76 return -EINVAL;
77
78 adreno_dev = ADRENO_DEVICE(device);
79
80 if (cattr->reg == NULL)
81 return -EINVAL;
82
83 ret = kstrtoul(buf, 0, &val);
84 if (ret)
85 return ret;
86
87 mutex_lock(&device->mutex);
88
89 /* Ignore writes while coresight is off */
90 if (!test_bit(ADRENO_DEVICE_CORESIGHT, &adreno_dev->priv))
91 goto out;
92
93 cattr->reg->value = val;
94
95 /* Program the hardware if it is not power collapsed */
96 if (device->state == KGSL_STATE_ACTIVE ||
97 device->state == KGSL_STATE_NAP) {
98 if (!kgsl_active_count_get(device)) {
99 kgsl_regwrite(device, cattr->reg->offset,
100 cattr->reg->value);
101 kgsl_active_count_put(device);
102 }
103 }
104
105out:
106 mutex_unlock(&device->mutex);
107 return size;
108}
109
110/**
111 * adreno_coresight_disable() - Generic function to disable coresight debugging
112 * @csdev: Pointer to coresight's device struct
113 *
114 * This is a generic function to disable coresight debug bus on adreno
115 * devices. This should be used in all cases of disabling
116 * coresight debug bus for adreno devices. This function in turn calls
117 * the adreno device specific function through the gpudev hook.
118 * This function is registered as the coresight disable function
119 * with coresight driver. It should only be called through coresight driver
120 * as that would ensure that the necessary setup required to be done on
121 * coresight driver's part is also done.
122 */
123static void adreno_coresight_disable(struct coresight_device *csdev,
124 struct perf_event *event)
125{
126 struct kgsl_device *device = dev_get_drvdata(csdev->dev.parent);
127 struct adreno_device *adreno_dev;
128 struct adreno_gpudev *gpudev;
129 struct adreno_coresight *coresight;
130 int i;
131
132 if (device == NULL)
133 return;
134
135 adreno_dev = ADRENO_DEVICE(device);
136 gpudev = ADRENO_GPU_DEVICE(adreno_dev);
137
138 coresight = gpudev->coresight;
139
140 if (coresight == NULL)
141 return;
142
143 mutex_lock(&device->mutex);
144
145 if (!kgsl_active_count_get(device)) {
146 for (i = 0; i < coresight->count; i++)
147 kgsl_regwrite(device, coresight->registers[i].offset,
148 0);
149
150 kgsl_active_count_put(device);
151 }
152
153 clear_bit(ADRENO_DEVICE_CORESIGHT, &adreno_dev->priv);
154
155 mutex_unlock(&device->mutex);
156}
157
158/**
159 * _adreno_coresight_get_and_clear(): Save the current value of coresight
160 * registers and clear the registers subsequently. Clearing registers
161 * has the effect of disabling coresight.
162 * @adreno_dev: Pointer to adreno device struct
163 */
164static int _adreno_coresight_get_and_clear(struct adreno_device *adreno_dev)
165{
166 struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
167 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
168 struct adreno_coresight *coresight = gpudev->coresight;
169 int i;
170
171 if (coresight == NULL)
172 return -ENODEV;
173
174 kgsl_pre_hwaccess(device);
175 /*
176 * Save the current value of each coresight register
177 * and then clear each register
178 */
179 for (i = 0; i < coresight->count; i++) {
180 kgsl_regread(device, coresight->registers[i].offset,
181 &coresight->registers[i].value);
182 kgsl_regwrite(device, coresight->registers[i].offset,
183 0);
184 }
185
186 return 0;
187}
188
189static int _adreno_coresight_set(struct adreno_device *adreno_dev)
190{
191 struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
192 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
193 struct adreno_coresight *coresight = gpudev->coresight;
194 int i;
195
196 if (coresight == NULL)
197 return -ENODEV;
198
199 for (i = 0; i < coresight->count; i++)
200 kgsl_regwrite(device, coresight->registers[i].offset,
201 coresight->registers[i].value);
202
203 kgsl_property_read_u32(device, "coresight-atid",
204 (unsigned int *)&(coresight->atid));
205
206 return 0;
207}
208/**
209 * adreno_coresight_enable() - Generic function to enable coresight debugging
210 * @csdev: Pointer to coresight's device struct
211 *
212 * This is a generic function to enable coresight debug bus on adreno
213 * devices. This should be used in all cases of enabling
214 * coresight debug bus for adreno devices. This function is registered as the
215 * coresight enable function with coresight driver. It should only be called
216 * through coresight driver as that would ensure that the necessary setup
217 * required to be done on coresight driver's part is also done.
218 */
219static int adreno_coresight_enable(struct coresight_device *csdev,
220 struct perf_event *event, u32 mode)
221{
222 struct kgsl_device *device = dev_get_drvdata(csdev->dev.parent);
223 struct adreno_device *adreno_dev;
224 struct adreno_gpudev *gpudev;
225 struct adreno_coresight *coresight;
226 int ret = 0;
227
228 if (device == NULL)
229 return -ENODEV;
230
231 adreno_dev = ADRENO_DEVICE(device);
232 gpudev = ADRENO_GPU_DEVICE(adreno_dev);
233
234 coresight = gpudev->coresight;
235
236 if (coresight == NULL)
237 return -ENODEV;
238
239 mutex_lock(&device->mutex);
240 if (!test_and_set_bit(ADRENO_DEVICE_CORESIGHT, &adreno_dev->priv)) {
241 int i;
242
243 /* Reset all the debug registers to their default values */
244
245 for (i = 0; i < coresight->count; i++)
246 coresight->registers[i].value =
247 coresight->registers[i].initial;
248
249 if (kgsl_state_is_awake(device)) {
250 ret = kgsl_active_count_get(device);
251 if (!ret) {
252 ret = _adreno_coresight_set(adreno_dev);
253 kgsl_active_count_put(device);
254 }
255 }
256 }
257
258 mutex_unlock(&device->mutex);
259
260 return ret;
261}
262
263/**
264 * adreno_coresight_start() - Reprogram coresight registers after power collapse
265 * @adreno_dev: Pointer to the adreno device structure
266 *
267 * Cache the current coresight register values so they can be restored after
268 * power collapse
269 */
270void adreno_coresight_stop(struct adreno_device *adreno_dev)
271{
272 if (test_bit(ADRENO_DEVICE_CORESIGHT, &adreno_dev->priv))
273 _adreno_coresight_get_and_clear(adreno_dev);
274}
275
276/**
277 * adreno_coresight_start() - Reprogram coresight registers after power collapse
278 * @adreno_dev: Pointer to the adreno device structure
279 *
280 * Reprogram the cached values to the coresight registers on power up
281 */
282void adreno_coresight_start(struct adreno_device *adreno_dev)
283{
284 if (test_bit(ADRENO_DEVICE_CORESIGHT, &adreno_dev->priv))
285 _adreno_coresight_set(adreno_dev);
286}
287
288static int adreno_coresight_trace_id(struct coresight_device *csdev)
289{
290 struct kgsl_device *device = dev_get_drvdata(csdev->dev.parent);
291 struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(ADRENO_DEVICE(device));
292
293 return gpudev->coresight->atid;
294}
295
296static const struct coresight_ops_source adreno_coresight_source_ops = {
297 .trace_id = adreno_coresight_trace_id,
298 .enable = adreno_coresight_enable,
299 .disable = adreno_coresight_disable,
300};
301
302static const struct coresight_ops adreno_coresight_ops = {
303 .source_ops = &adreno_coresight_source_ops,
304};
305
306void adreno_coresight_remove(struct adreno_device *adreno_dev)
307{
308 coresight_unregister(adreno_dev->csdev);
309 adreno_dev->csdev = NULL;
310}
311
312int adreno_coresight_init(struct adreno_device *adreno_dev)
313{
314 int ret = 0;
315 struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
316 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
317 struct coresight_desc desc;
318
319 if (gpudev->coresight == NULL)
320 return -ENODEV;
321
322 if (!IS_ERR_OR_NULL(adreno_dev->csdev))
323 return 0;
324
325 memset(&desc, 0, sizeof(desc));
326
327 desc.pdata = of_get_coresight_platform_data(&device->pdev->dev,
328 device->pdev->dev.of_node);
329 if (IS_ERR_OR_NULL(desc.pdata))
330 return (desc.pdata == NULL) ? -ENODEV :
331 PTR_ERR(desc.pdata);
332
333 desc.type = CORESIGHT_DEV_TYPE_SOURCE;
334 desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_BUS;
335 desc.ops = &adreno_coresight_ops;
336 desc.dev = &device->pdev->dev;
337 desc.groups = gpudev->coresight->groups;
338
339 adreno_dev->csdev = coresight_register(&desc);
340
341 if (IS_ERR(adreno_dev->csdev))
342 ret = PTR_ERR(adreno_dev->csdev);
343
344 return ret;
345}