blob: 282897823ef5898ac980d43889f76317f945d0c8 [file] [log] [blame]
Satyajit Desaif151d682016-09-12 16:18:03 -07001/* Copyright (c) 2014-2016, 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/kernel.h>
14#include <linux/module.h>
15#include <linux/device.h>
16#include <linux/platform_device.h>
17#include <linux/io.h>
18#include <linux/err.h>
19#include <linux/fs.h>
20#include <linux/clk.h>
21#include <linux/bitmap.h>
22#include <linux/of.h>
23#include <linux/coresight.h>
24
25#include "coresight-priv.h"
26
27#define tpdm_writel(drvdata, val, off) __raw_writel((val), drvdata->base + off)
28#define tpdm_readl(drvdata, off) __raw_readl(drvdata->base + off)
29
30#define TPDM_LOCK(drvdata) \
31do { \
32 mb(); /* ensure configuration take effect before we lock it */ \
33 tpdm_writel(drvdata, 0x0, CORESIGHT_LAR); \
34} while (0)
35#define TPDM_UNLOCK(drvdata) \
36do { \
37 tpdm_writel(drvdata, CORESIGHT_UNLOCK, CORESIGHT_LAR); \
38 mb(); /* ensure unlock take effect before we configure */ \
39} while (0)
40
41/* GPR Registers */
42#define TPDM_GPR_CR(n) (0x0 + (n * 4))
43
44/* BC Subunit Registers */
45#define TPDM_BC_CR (0x280)
46#define TPDM_BC_SATROLL (0x284)
47#define TPDM_BC_CNTENSET (0x288)
48#define TPDM_BC_CNTENCLR (0x28C)
49#define TPDM_BC_INTENSET (0x290)
50#define TPDM_BC_INTENCLR (0x294)
51#define TPDM_BC_TRIG_LO(n) (0x298 + (n * 4))
52#define TPDM_BC_TRIG_HI(n) (0x318 + (n * 4))
53#define TPDM_BC_GANG (0x398)
54#define TPDM_BC_OVERFLOW(n) (0x39C + (n * 4))
55#define TPDM_BC_OVSR (0x3C0)
56#define TPDM_BC_SELR (0x3C4)
57#define TPDM_BC_CNTR_LO (0x3C8)
58#define TPDM_BC_CNTR_HI (0x3CC)
59#define TPDM_BC_SHADOW_LO(n) (0x3D0 + (n * 4))
60#define TPDM_BC_SHADOW_HI(n) (0x450 + (n * 4))
61#define TPDM_BC_SWINC (0x4D0)
62#define TPDM_BC_MSR(n) (0x4F0 + (n * 4))
63
64/* TC Subunit Registers */
65#define TPDM_TC_CR (0x500)
66#define TPDM_TC_CNTENSET (0x504)
67#define TPDM_TC_CNTENCLR (0x508)
68#define TPDM_TC_INTENSET (0x50C)
69#define TPDM_TC_INTENCLR (0x510)
70#define TPDM_TC_TRIG_SEL(n) (0x514 + (n * 4))
71#define TPDM_TC_TRIG_LO(n) (0x534 + (n * 4))
72#define TPDM_TC_TRIG_HI(n) (0x554 + (n * 4))
73#define TPDM_TC_OVSR_GP (0x580)
74#define TPDM_TC_OVSR_IMPL (0x584)
75#define TPDM_TC_SELR (0x588)
76#define TPDM_TC_CNTR_LO (0x58C)
77#define TPDM_TC_CNTR_HI (0x590)
78#define TPDM_TC_SHADOW_LO(n) (0x594 + (n * 4))
79#define TPDM_TC_SHADOW_HI(n) (0x644 + (n * 4))
80#define TPDM_TC_SWINC (0x700)
81#define TPDM_TC_MSR(n) (0x768 + (n * 4))
82
83/* DSB Subunit Registers */
84#define TPDM_DSB_CR (0x780)
85#define TPDM_DSB_TIER (0x784)
86#define TPDM_DSB_TPR(n) (0x788 + (n * 4))
87#define TPDM_DSB_TPMR(n) (0x7A8 + (n * 4))
88#define TPDM_DSB_XPR(n) (0x7C8 + (n * 4))
89#define TPDM_DSB_XPMR(n) (0x7E8 + (n * 4))
90#define TPDM_DSB_EDCR(n) (0x808 + (n * 4))
91#define TPDM_DSB_EDCMR(n) (0x848 + (n * 4))
92#define TPDM_DSB_CA_SELECT(n) (0x86c + (n * 4))
93#define TPDM_DSB_MSR(n) (0x980 + (n * 4))
94
95/* CMB Subunit Registers */
96#define TPDM_CMB_CR (0xA00)
97#define TPDM_CMB_TIER (0xA04)
98#define TPDM_CMB_TPR(n) (0xA08 + (n * 4))
99#define TPDM_CMB_TPMR(n) (0xA10 + (n * 4))
100#define TPDM_CMB_XPR(n) (0xA18 + (n * 4))
101#define TPDM_CMB_XPMR(n) (0xA20 + (n * 4))
102#define TPDM_CMB_MSR(n) (0xA80 + (n * 4))
103
104/* TPDM Specific Registers */
105#define TPDM_ITATBCNTRL (0xEF0)
106#define TPDM_CLK_CTRL (0x220)
107
108#define TPDM_DATASETS 32
109#define TPDM_BC_MAX_COUNTERS 32
110#define TPDM_BC_MAX_OVERFLOW 6
111#define TPDM_BC_MAX_MSR 4
112#define TPDM_TC_MAX_COUNTERS 44
113#define TPDM_TC_MAX_TRIG 8
114#define TPDM_TC_MAX_MSR 6
115#define TPDM_DSB_MAX_PATT 8
116#define TPDM_DSB_MAX_SELECT 8
117#define TPDM_DSB_MAX_MSR 32
118#define TPDM_DSB_MAX_EDCR 16
119#define TPDM_DSB_MAX_LINES 256
120#define TPDM_CMB_PATT_CMP 2
121#define TPDM_CMB_MAX_MSR 128
122
123/* DSB programming modes */
124#define TPDM_DSB_MODE_CYCACC(val) BMVAL(val, 0, 2)
125#define TPDM_DSB_MODE_PERF BIT(3)
126#define TPDM_DSB_MODE_HPBYTESEL(val) BMVAL(val, 4, 8)
127#define TPDM_MODE_ALL (0xFFFFFFF)
128
129#define NUM_OF_BITS 32
130#define TPDM_GPR_REGS_MAX 160
131
132#define TPDM_TRACE_ID_START 128
133
134#define TPDM_REVISION_A 0
135#define TPDM_REVISION_B 1
136
137enum tpdm_dataset {
138 TPDM_DS_IMPLDEF,
139 TPDM_DS_DSB,
140 TPDM_DS_CMB,
141 TPDM_DS_TC,
142 TPDM_DS_BC,
143 TPDM_DS_GPR,
144};
145
146enum tpdm_mode {
147 TPDM_MODE_ATB,
148 TPDM_MODE_APB,
149};
150
151enum tpdm_support_type {
152 TPDM_SUPPORT_TYPE_FULL,
153 TPDM_SUPPORT_TYPE_PARTIAL,
154 TPDM_SUPPORT_TYPE_NO,
155};
156
157enum tpdm_cmb_mode {
158 TPDM_CMB_MODE_CONTINUOUS,
159 TPDM_CMB_MODE_TRACE_ON_CHANGE,
160};
161
162enum tpdm_cmb_patt_bits {
163 TPDM_CMB_LSB,
164 TPDM_CMB_MSB,
165};
166
167#ifdef CONFIG_CORESIGHT_TPDM_DEFAULT_ENABLE
168static int boot_enable = 1;
169#else
170static int boot_enable;
171#endif
172
173module_param_named(
174 boot_enable, boot_enable, int, S_IRUGO
175);
176
177struct gpr_dataset {
178 DECLARE_BITMAP(gpr_dirty, TPDM_GPR_REGS_MAX);
179 uint32_t gp_regs[TPDM_GPR_REGS_MAX];
180};
181
182struct bc_dataset {
183 enum tpdm_mode capture_mode;
184 enum tpdm_mode retrieval_mode;
185 uint32_t sat_mode;
186 uint32_t enable_counters;
187 uint32_t clear_counters;
188 uint32_t enable_irq;
189 uint32_t clear_irq;
190 uint32_t trig_val_lo[TPDM_BC_MAX_COUNTERS];
191 uint32_t trig_val_hi[TPDM_BC_MAX_COUNTERS];
192 uint32_t enable_ganging;
193 uint32_t overflow_val[TPDM_BC_MAX_OVERFLOW];
194 uint32_t msr[TPDM_BC_MAX_MSR];
195};
196
197struct tc_dataset {
198 enum tpdm_mode capture_mode;
199 enum tpdm_mode retrieval_mode;
200 bool sat_mode;
201 uint32_t enable_counters;
202 uint32_t clear_counters;
203 uint32_t enable_irq;
204 uint32_t clear_irq;
205 uint32_t trig_sel[TPDM_TC_MAX_TRIG];
206 uint32_t trig_val_lo[TPDM_TC_MAX_TRIG];
207 uint32_t trig_val_hi[TPDM_TC_MAX_TRIG];
208 uint32_t msr[TPDM_TC_MAX_MSR];
209};
210
211struct dsb_dataset {
212 uint32_t mode;
213 uint32_t edge_ctrl[TPDM_DSB_MAX_EDCR];
214 uint32_t edge_ctrl_mask[TPDM_DSB_MAX_EDCR / 2];
215 uint32_t patt_val[TPDM_DSB_MAX_PATT];
216 uint32_t patt_mask[TPDM_DSB_MAX_PATT];
217 bool patt_ts;
218 bool patt_type;
219 uint32_t trig_patt_val[TPDM_DSB_MAX_PATT];
220 uint32_t trig_patt_mask[TPDM_DSB_MAX_PATT];
221 bool trig_ts;
222 uint32_t select_val[TPDM_DSB_MAX_SELECT];
223 uint32_t msr[TPDM_DSB_MAX_MSR];
224};
225
226struct cmb_dataset {
227 enum tpdm_cmb_mode mode;
228 uint32_t patt_val[TPDM_CMB_PATT_CMP];
229 uint32_t patt_mask[TPDM_CMB_PATT_CMP];
230 bool patt_ts;
231 uint32_t trig_patt_val[TPDM_CMB_PATT_CMP];
232 uint32_t trig_patt_mask[TPDM_CMB_PATT_CMP];
233 bool trig_ts;
234 uint32_t msr[TPDM_CMB_MAX_MSR];
235};
236
237struct tpdm_drvdata {
238 void __iomem *base;
239 struct device *dev;
240 struct coresight_device *csdev;
241 struct clk *clk;
242 struct mutex lock;
243 bool enable;
244 bool clk_enable;
245 DECLARE_BITMAP(datasets, TPDM_DATASETS);
246 DECLARE_BITMAP(enable_ds, TPDM_DATASETS);
247 enum tpdm_support_type tc_trig_type;
248 enum tpdm_support_type bc_trig_type;
249 enum tpdm_support_type bc_gang_type;
250 uint32_t bc_counters_avail;
251 uint32_t tc_counters_avail;
252 struct gpr_dataset *gpr;
253 struct bc_dataset *bc;
254 struct tc_dataset *tc;
255 struct dsb_dataset *dsb;
256 struct cmb_dataset *cmb;
257 int traceid;
258 uint32_t version;
259 bool msr_support;
260 bool msr_fix_req;
261};
262
263static void __tpdm_enable_gpr(struct tpdm_drvdata *drvdata)
264{
265 int i;
266
267 for (i = 0; i < TPDM_GPR_REGS_MAX; i++) {
268 if (!test_bit(i, drvdata->gpr->gpr_dirty))
269 continue;
270 tpdm_writel(drvdata, drvdata->gpr->gp_regs[i], TPDM_GPR_CR(i));
271 }
272}
273
274static void __tpdm_config_bc_msr(struct tpdm_drvdata *drvdata)
275{
276 int i;
277
278 if (!drvdata->msr_support)
279 return;
280
281 for (i = 0; i < TPDM_BC_MAX_MSR; i++)
282 tpdm_writel(drvdata, drvdata->bc->msr[i], TPDM_BC_MSR(i));
283}
284
285static void __tpdm_config_tc_msr(struct tpdm_drvdata *drvdata)
286{
287 int i;
288
289 if (!drvdata->msr_support)
290 return;
291
292 for (i = 0; i < TPDM_TC_MAX_MSR; i++)
293 tpdm_writel(drvdata, drvdata->tc->msr[i], TPDM_TC_MSR(i));
294}
295
296static void __tpdm_config_dsb_msr(struct tpdm_drvdata *drvdata)
297{
298 int i;
299
300 if (!drvdata->msr_support)
301 return;
302
303 for (i = 0; i < TPDM_DSB_MAX_MSR; i++)
304 tpdm_writel(drvdata, drvdata->dsb->msr[i], TPDM_DSB_MSR(i));
305}
306
307static void __tpdm_config_cmb_msr(struct tpdm_drvdata *drvdata)
308{
309 int i;
310
311 if (!drvdata->msr_support)
312 return;
313
314 for (i = 0; i < TPDM_CMB_MAX_MSR; i++)
315 tpdm_writel(drvdata, drvdata->cmb->msr[i], TPDM_CMB_MSR(i));
316}
317
318static void __tpdm_enable_bc(struct tpdm_drvdata *drvdata)
319{
320 int i;
321 uint32_t val;
322
323 if (drvdata->bc->sat_mode)
324 tpdm_writel(drvdata, drvdata->bc->sat_mode,
325 TPDM_BC_SATROLL);
326 else
327 tpdm_writel(drvdata, 0x0, TPDM_BC_SATROLL);
328
329 if (drvdata->bc->enable_counters) {
330 tpdm_writel(drvdata, 0xFFFFFFFF, TPDM_BC_CNTENCLR);
331 tpdm_writel(drvdata, drvdata->bc->enable_counters,
332 TPDM_BC_CNTENSET);
333 }
334 if (drvdata->bc->clear_counters)
335 tpdm_writel(drvdata, drvdata->bc->clear_counters,
336 TPDM_BC_CNTENCLR);
337
338 if (drvdata->bc->enable_irq) {
339 tpdm_writel(drvdata, 0xFFFFFFFF, TPDM_BC_INTENCLR);
340 tpdm_writel(drvdata, drvdata->bc->enable_irq,
341 TPDM_BC_INTENSET);
342 }
343 if (drvdata->bc->clear_irq)
344 tpdm_writel(drvdata, drvdata->bc->clear_irq,
345 TPDM_BC_INTENCLR);
346
347 if (drvdata->bc_trig_type == TPDM_SUPPORT_TYPE_FULL) {
348 for (i = 0; i < drvdata->bc_counters_avail; i++) {
349 tpdm_writel(drvdata, drvdata->bc->trig_val_lo[i],
350 TPDM_BC_TRIG_LO(i));
351 tpdm_writel(drvdata, drvdata->bc->trig_val_hi[i],
352 TPDM_BC_TRIG_HI(i));
353 }
354 } else if (drvdata->bc_trig_type == TPDM_SUPPORT_TYPE_PARTIAL) {
355 tpdm_writel(drvdata, drvdata->bc->trig_val_lo[0],
356 TPDM_BC_TRIG_LO(0));
357 tpdm_writel(drvdata, drvdata->bc->trig_val_hi[0],
358 TPDM_BC_TRIG_HI(0));
359 }
360
361 if (drvdata->bc->enable_ganging)
362 tpdm_writel(drvdata, drvdata->bc->enable_ganging, TPDM_BC_GANG);
363
364 for (i = 0; i < TPDM_BC_MAX_OVERFLOW; i++)
365 tpdm_writel(drvdata, drvdata->bc->overflow_val[i],
366 TPDM_BC_OVERFLOW(i));
367
368 __tpdm_config_bc_msr(drvdata);
369
370 val = tpdm_readl(drvdata, TPDM_BC_CR);
371 if (drvdata->bc->retrieval_mode == TPDM_MODE_APB)
372 val = val | BIT(2);
373 else
374 val = val & ~BIT(2);
375 tpdm_writel(drvdata, val, TPDM_BC_CR);
376
377 val = tpdm_readl(drvdata, TPDM_BC_CR);
378 /* Set the enable bit */
379 val = val | BIT(0);
380 tpdm_writel(drvdata, val, TPDM_BC_CR);
381}
382
383static void __tpdm_enable_tc(struct tpdm_drvdata *drvdata)
384{
385 int i;
386 uint32_t val;
387
388 if (drvdata->tc->enable_counters) {
389 tpdm_writel(drvdata, 0xF, TPDM_TC_CNTENCLR);
390 tpdm_writel(drvdata, drvdata->tc->enable_counters,
391 TPDM_TC_CNTENSET);
392 }
393 if (drvdata->tc->clear_counters)
394 tpdm_writel(drvdata, drvdata->tc->clear_counters,
395 TPDM_TC_CNTENCLR);
396
397 if (drvdata->tc->enable_irq) {
398 tpdm_writel(drvdata, 0xF, TPDM_TC_INTENCLR);
399 tpdm_writel(drvdata, drvdata->tc->enable_irq,
400 TPDM_TC_INTENSET);
401 }
402 if (drvdata->tc->clear_irq)
403 tpdm_writel(drvdata, drvdata->tc->clear_irq,
404 TPDM_TC_INTENCLR);
405
406 if (drvdata->tc_trig_type == TPDM_SUPPORT_TYPE_FULL) {
407 for (i = 0; i < TPDM_TC_MAX_TRIG; i++) {
408 tpdm_writel(drvdata, drvdata->tc->trig_sel[i],
409 TPDM_TC_TRIG_SEL(i));
410 tpdm_writel(drvdata, drvdata->tc->trig_val_lo[i],
411 TPDM_TC_TRIG_LO(i));
412 tpdm_writel(drvdata, drvdata->tc->trig_val_hi[i],
413 TPDM_TC_TRIG_HI(i));
414 }
415 } else if (drvdata->tc_trig_type == TPDM_SUPPORT_TYPE_PARTIAL) {
416 tpdm_writel(drvdata, drvdata->tc->trig_sel[0],
417 TPDM_TC_TRIG_SEL(0));
418 tpdm_writel(drvdata, drvdata->tc->trig_val_lo[0],
419 TPDM_TC_TRIG_LO(0));
420 tpdm_writel(drvdata, drvdata->tc->trig_val_hi[0],
421 TPDM_TC_TRIG_HI(0));
422 }
423
424 __tpdm_config_tc_msr(drvdata);
425
426 val = tpdm_readl(drvdata, TPDM_TC_CR);
427 if (drvdata->tc->sat_mode)
428 val = val | BIT(4);
429 else
430 val = val & ~BIT(4);
431 if (drvdata->tc->retrieval_mode == TPDM_MODE_APB)
432 val = val | BIT(2);
433 else
434 val = val & ~BIT(2);
435 tpdm_writel(drvdata, val, TPDM_TC_CR);
436
437 val = tpdm_readl(drvdata, TPDM_TC_CR);
438 /* Set the enable bit */
439 val = val | BIT(0);
440 tpdm_writel(drvdata, val, TPDM_TC_CR);
441}
442
443static void __tpdm_enable_dsb(struct tpdm_drvdata *drvdata)
444{
445 uint32_t val, mode, i;
446
447 for (i = 0; i < TPDM_DSB_MAX_EDCR; i++)
448 tpdm_writel(drvdata, drvdata->dsb->edge_ctrl[i],
449 TPDM_DSB_EDCR(i));
450 for (i = 0; i < TPDM_DSB_MAX_EDCR / 2; i++)
451 tpdm_writel(drvdata, drvdata->dsb->edge_ctrl_mask[i],
452 TPDM_DSB_EDCMR(i));
453
454 for (i = 0; i < TPDM_DSB_MAX_PATT; i++) {
455 tpdm_writel(drvdata, drvdata->dsb->patt_val[i],
456 TPDM_DSB_TPR(i));
457 tpdm_writel(drvdata, drvdata->dsb->patt_mask[i],
458 TPDM_DSB_TPMR(i));
459 }
460
461 for (i = 0; i < TPDM_DSB_MAX_PATT; i++) {
462 tpdm_writel(drvdata, drvdata->dsb->trig_patt_val[i],
463 TPDM_DSB_XPR(i));
464 tpdm_writel(drvdata, drvdata->dsb->trig_patt_mask[i],
465 TPDM_DSB_XPMR(i));
466 }
467
468 for (i = 0; i < TPDM_DSB_MAX_SELECT; i++)
469 tpdm_writel(drvdata, drvdata->dsb->select_val[i],
470 TPDM_DSB_CA_SELECT(i));
471
472 val = tpdm_readl(drvdata, TPDM_DSB_TIER);
473 if (drvdata->dsb->patt_ts == true) {
474 val = val | BIT(0);
475 if (drvdata->dsb->patt_type == true)
476 val = val | BIT(2);
477 else
478 val = val & ~BIT(2);
479 } else {
480 val = val & ~BIT(0);
481 }
482 if (drvdata->dsb->trig_ts == true)
483 val = val | BIT(1);
484 else
485 val = val & ~BIT(1);
486 tpdm_writel(drvdata, val, TPDM_DSB_TIER);
487
488 if (!drvdata->msr_fix_req)
489 __tpdm_config_dsb_msr(drvdata);
490
491 val = tpdm_readl(drvdata, TPDM_DSB_CR);
492 /* Set the cycle accurate mode */
493 mode = TPDM_DSB_MODE_CYCACC(drvdata->dsb->mode);
494 val = val & ~(0x7 << 9);
495 val = val | (mode << 9);
496 /* Set the byte lane for high-performance mode */
497 mode = TPDM_DSB_MODE_HPBYTESEL(drvdata->dsb->mode);
498 val = val & ~(0x1F << 2);
499 val = val | (mode << 2);
500 /* Set the performance mode */
501 if (drvdata->dsb->mode & TPDM_DSB_MODE_PERF)
502 val = val | BIT(1);
503 else
504 val = val & ~BIT(1);
505 tpdm_writel(drvdata, val, TPDM_DSB_CR);
506
507 val = tpdm_readl(drvdata, TPDM_DSB_CR);
508 /* Set the enable bit */
509 val = val | BIT(0);
510 tpdm_writel(drvdata, val, TPDM_DSB_CR);
511
512 if (drvdata->msr_fix_req)
513 __tpdm_config_dsb_msr(drvdata);
514}
515
516static void __tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
517{
518 uint32_t val;
519
520 tpdm_writel(drvdata, drvdata->cmb->patt_val[TPDM_CMB_LSB],
521 TPDM_CMB_TPR(TPDM_CMB_LSB));
522 tpdm_writel(drvdata, drvdata->cmb->patt_mask[TPDM_CMB_LSB],
523 TPDM_CMB_TPMR(TPDM_CMB_LSB));
524 tpdm_writel(drvdata, drvdata->cmb->patt_val[TPDM_CMB_MSB],
525 TPDM_CMB_TPR(TPDM_CMB_MSB));
526 tpdm_writel(drvdata, drvdata->cmb->patt_mask[TPDM_CMB_MSB],
527 TPDM_CMB_TPMR(TPDM_CMB_MSB));
528
529 tpdm_writel(drvdata, drvdata->cmb->trig_patt_val[TPDM_CMB_LSB],
530 TPDM_CMB_XPR(TPDM_CMB_LSB));
531 tpdm_writel(drvdata, drvdata->cmb->trig_patt_mask[TPDM_CMB_LSB],
532 TPDM_CMB_XPMR(TPDM_CMB_LSB));
533 tpdm_writel(drvdata, drvdata->cmb->trig_patt_val[TPDM_CMB_MSB],
534 TPDM_CMB_XPR(TPDM_CMB_MSB));
535 tpdm_writel(drvdata, drvdata->cmb->trig_patt_mask[TPDM_CMB_MSB],
536 TPDM_CMB_XPMR(TPDM_CMB_MSB));
537
538 val = tpdm_readl(drvdata, TPDM_CMB_TIER);
539 if (drvdata->cmb->patt_ts == true)
540 val = val | BIT(0);
541 else
542 val = val & ~BIT(0);
543 if (drvdata->cmb->trig_ts == true)
544 val = val | BIT(1);
545 else
546 val = val & ~BIT(1);
547 tpdm_writel(drvdata, val, TPDM_CMB_TIER);
548
549 __tpdm_config_cmb_msr(drvdata);
550
551 val = tpdm_readl(drvdata, TPDM_CMB_CR);
552 /* Set the flow control bit */
553 val = val & ~BIT(2);
554 if (drvdata->cmb->mode == TPDM_CMB_MODE_CONTINUOUS)
555 val = val & ~BIT(1);
556 else
557 val = val | BIT(1);
558 tpdm_writel(drvdata, val, TPDM_CMB_CR);
559 /* Set the enable bit */
560 val = val | BIT(0);
561 tpdm_writel(drvdata, val, TPDM_CMB_CR);
562}
563
564static void __tpdm_enable(struct tpdm_drvdata *drvdata)
565{
566 TPDM_UNLOCK(drvdata);
567
568 if (drvdata->clk_enable)
569 tpdm_writel(drvdata, 0x1, TPDM_CLK_CTRL);
570
571 if (test_bit(TPDM_DS_GPR, drvdata->enable_ds))
572 __tpdm_enable_gpr(drvdata);
573
574 if (test_bit(TPDM_DS_BC, drvdata->enable_ds))
575 __tpdm_enable_bc(drvdata);
576
577 if (test_bit(TPDM_DS_TC, drvdata->enable_ds))
578 __tpdm_enable_tc(drvdata);
579
580 if (test_bit(TPDM_DS_DSB, drvdata->enable_ds))
581 __tpdm_enable_dsb(drvdata);
582
583 if (test_bit(TPDM_DS_CMB, drvdata->enable_ds))
584 __tpdm_enable_cmb(drvdata);
585
586 TPDM_LOCK(drvdata);
587}
588
589static int tpdm_enable(struct coresight_device *csdev,
590 struct perf_event_attr *attr, u32 mode)
591{
592 struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
593 int ret;
594
595 ret = clk_prepare_enable(drvdata->clk);
596 if (ret)
597 return ret;
598
599 mutex_lock(&drvdata->lock);
600 __tpdm_enable(drvdata);
601 drvdata->enable = true;
602 mutex_unlock(&drvdata->lock);
603
604 dev_info(drvdata->dev, "TPDM tracing enabled\n");
605 return 0;
606}
607
608static void __tpdm_disable_bc(struct tpdm_drvdata *drvdata)
609{
610 uint32_t config;
611
612 config = tpdm_readl(drvdata, TPDM_BC_CR);
613 config = config & ~BIT(0);
614 tpdm_writel(drvdata, config, TPDM_BC_CR);
615}
616
617static void __tpdm_disable_tc(struct tpdm_drvdata *drvdata)
618{
619 uint32_t config;
620
621 config = tpdm_readl(drvdata, TPDM_TC_CR);
622 config = config & ~BIT(0);
623 tpdm_writel(drvdata, config, TPDM_TC_CR);
624}
625
626static void __tpdm_disable_dsb(struct tpdm_drvdata *drvdata)
627{
628 uint32_t config;
629
630 config = tpdm_readl(drvdata, TPDM_DSB_CR);
631 config = config & ~BIT(0);
632 tpdm_writel(drvdata, config, TPDM_DSB_CR);
633}
634
635static void __tpdm_disable_cmb(struct tpdm_drvdata *drvdata)
636{
637 uint32_t config;
638
639 config = tpdm_readl(drvdata, TPDM_CMB_CR);
640 config = config & ~BIT(0);
641 tpdm_writel(drvdata, config, TPDM_CMB_CR);
642}
643
644static void __tpdm_disable(struct tpdm_drvdata *drvdata)
645{
646 TPDM_UNLOCK(drvdata);
647
648 if (test_bit(TPDM_DS_BC, drvdata->enable_ds))
649 __tpdm_disable_bc(drvdata);
650
651 if (test_bit(TPDM_DS_TC, drvdata->enable_ds))
652 __tpdm_disable_tc(drvdata);
653
654 if (test_bit(TPDM_DS_DSB, drvdata->enable_ds))
655 __tpdm_disable_dsb(drvdata);
656
657 if (test_bit(TPDM_DS_CMB, drvdata->enable_ds))
658 __tpdm_disable_cmb(drvdata);
659
660 if (drvdata->clk_enable)
661 tpdm_writel(drvdata, 0x0, TPDM_CLK_CTRL);
662
663 TPDM_LOCK(drvdata);
664}
665
666static void tpdm_disable(struct coresight_device *csdev)
667{
668 struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
669
670 mutex_lock(&drvdata->lock);
671 __tpdm_disable(drvdata);
672 drvdata->enable = false;
673 mutex_unlock(&drvdata->lock);
674
675 clk_disable_unprepare(drvdata->clk);
676
677 dev_info(drvdata->dev, "TPDM tracing disabled\n");
678}
679
680static int tpdm_trace_id(struct coresight_device *csdev)
681{
682 struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
683
684 return drvdata->traceid;
685}
686
687static const struct coresight_ops_source tpdm_source_ops = {
688 .trace_id = tpdm_trace_id,
689 .enable = tpdm_enable,
690 .disable = tpdm_disable,
691};
692
693static const struct coresight_ops tpdm_cs_ops = {
694 .source_ops = &tpdm_source_ops,
695};
696
697static ssize_t tpdm_show_available_datasets(struct device *dev,
698 struct device_attribute *attr,
699 char *buf)
700{
701 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
702 ssize_t size = 0;
703
704 if (test_bit(TPDM_DS_IMPLDEF, drvdata->datasets))
705 size += scnprintf(buf + size, PAGE_SIZE - size, "%-8s",
706 "IMPLDEF");
707
708 if (test_bit(TPDM_DS_DSB, drvdata->datasets))
709 size += scnprintf(buf + size, PAGE_SIZE - size, "%-8s", "DSB");
710
711 if (test_bit(TPDM_DS_CMB, drvdata->datasets))
712 size += scnprintf(buf + size, PAGE_SIZE - size, "%-8s", "CMB");
713
714 if (test_bit(TPDM_DS_TC, drvdata->datasets))
715 size += scnprintf(buf + size, PAGE_SIZE - size, "%-8s", "TC");
716
717 if (test_bit(TPDM_DS_BC, drvdata->datasets))
718 size += scnprintf(buf + size, PAGE_SIZE - size, "%-8s", "BC");
719
720 if (test_bit(TPDM_DS_GPR, drvdata->datasets))
721 size += scnprintf(buf + size, PAGE_SIZE - size, "%-8s", "GPR");
722
723 size += scnprintf(buf + size, PAGE_SIZE - size, "\n");
724 return size;
725}
726static DEVICE_ATTR(available_datasets, S_IRUGO, tpdm_show_available_datasets,
727 NULL);
728
729static ssize_t tpdm_show_enable_datasets(struct device *dev,
730 struct device_attribute *attr,
731 char *buf)
732{
733 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
734 ssize_t size;
735
736 size = scnprintf(buf, PAGE_SIZE, "%*pb\n", TPDM_DATASETS,
737 drvdata->enable_ds);
738
739 if (PAGE_SIZE - size < 2)
740 size = -EINVAL;
741 else
742 size += scnprintf(buf + size, 2, "\n");
743 return size;
744}
745
746static ssize_t tpdm_store_enable_datasets(struct device *dev,
747 struct device_attribute *attr,
748 const char *buf,
749 size_t size)
750{
751 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
752 unsigned long val;
753 int i;
754
755 if (kstrtoul(buf, 16, &val))
756 return -EINVAL;
757
758 mutex_lock(&drvdata->lock);
759 if (drvdata->enable) {
760 mutex_unlock(&drvdata->lock);
761 return -EPERM;
762 }
763
764 for (i = 0; i < TPDM_DATASETS; i++) {
765 if (test_bit(i, drvdata->datasets) && (val & BIT(i)))
766 __set_bit(i, drvdata->enable_ds);
767 else
768 __clear_bit(i, drvdata->enable_ds);
769 }
770 mutex_unlock(&drvdata->lock);
771 return size;
772}
773static DEVICE_ATTR(enable_datasets, S_IRUGO | S_IWUSR,
774 tpdm_show_enable_datasets, tpdm_store_enable_datasets);
775
776static ssize_t tpdm_show_gp_regs(struct device *dev,
777 struct device_attribute *attr,
778 char *buf)
779{
780 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
781 ssize_t size = 0;
782 int i = 0;
783
784 if (!test_bit(TPDM_DS_GPR, drvdata->datasets))
785 return -EPERM;
786
787 mutex_lock(&drvdata->lock);
788 for (i = 0; i < TPDM_GPR_REGS_MAX; i++) {
789 if (!test_bit(i, drvdata->gpr->gpr_dirty))
790 continue;
791 size += scnprintf(buf + size, PAGE_SIZE - size,
792 "Index: 0x%x Value: 0x%x\n", i,
793 drvdata->gpr->gp_regs[i]);
794 }
795 mutex_unlock(&drvdata->lock);
796 return size;
797}
798
799static ssize_t tpdm_store_gp_regs(struct device *dev,
800 struct device_attribute *attr,
801 const char *buf,
802 size_t size)
803{
804 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
805 unsigned long index, val;
806
807 if (sscanf(buf, "%lx %lx", &index, &val) != 2)
808 return -EINVAL;
809 if (!test_bit(TPDM_DS_GPR, drvdata->datasets) ||
810 index >= TPDM_GPR_REGS_MAX)
811 return -EPERM;
812
813 mutex_lock(&drvdata->lock);
814 drvdata->gpr->gp_regs[index] = val;
815 __set_bit(index, drvdata->gpr->gpr_dirty);
816 mutex_unlock(&drvdata->lock);
817 return size;
818}
819static DEVICE_ATTR(gp_regs, S_IRUGO | S_IWUSR, tpdm_show_gp_regs,
820 tpdm_store_gp_regs);
821
822static ssize_t tpdm_show_bc_capture_mode(struct device *dev,
823 struct device_attribute *attr,
824 char *buf)
825{
826 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
827
828 if (!test_bit(TPDM_DS_BC, drvdata->datasets))
829 return -EPERM;
830
831 return scnprintf(buf, PAGE_SIZE, "%s\n",
832 drvdata->bc->capture_mode == TPDM_MODE_ATB ?
833 "ATB" : "APB");
834}
835
836static ssize_t tpdm_store_bc_capture_mode(struct device *dev,
837 struct device_attribute *attr,
838 const char *buf,
839 size_t size)
840{
841 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
842 char str[20] = "";
843 uint32_t val;
844
845 if (size >= 20)
846 return -EINVAL;
847 if (sscanf(buf, "%s", str) != 1)
848 return -EINVAL;
849 if (!test_bit(TPDM_DS_BC, drvdata->enable_ds))
850 return -EPERM;
851
852 mutex_lock(&drvdata->lock);
853 if (!drvdata->enable) {
854 mutex_unlock(&drvdata->lock);
855 return -EPERM;
856 }
857
858 if (!strcmp(str, "ATB")) {
859 drvdata->bc->capture_mode = TPDM_MODE_ATB;
860 } else if (!strcmp(str, "APB") &&
861 drvdata->bc->retrieval_mode == TPDM_MODE_APB) {
862
863 TPDM_UNLOCK(drvdata);
864 val = tpdm_readl(drvdata, TPDM_BC_CR);
865 val = val | BIT(3);
866 tpdm_writel(drvdata, val, TPDM_BC_CR);
867 TPDM_LOCK(drvdata);
868
869 drvdata->bc->capture_mode = TPDM_MODE_APB;
870 } else {
871 mutex_unlock(&drvdata->lock);
872 return -EINVAL;
873 }
874 mutex_unlock(&drvdata->lock);
875 return size;
876}
877static DEVICE_ATTR(bc_capture_mode, S_IRUGO | S_IWUSR,
878 tpdm_show_bc_capture_mode, tpdm_store_bc_capture_mode);
879
880static ssize_t tpdm_show_bc_retrieval_mode(struct device *dev,
881 struct device_attribute *attr,
882 char *buf)
883{
884 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
885
886 if (!test_bit(TPDM_DS_BC, drvdata->datasets))
887 return -EPERM;
888
889 return scnprintf(buf, PAGE_SIZE, "%s\n",
890 drvdata->bc->retrieval_mode == TPDM_MODE_ATB ?
891 "ATB" : "APB");
892}
893
894static ssize_t tpdm_store_bc_retrieval_mode(struct device *dev,
895 struct device_attribute *attr,
896 const char *buf,
897 size_t size)
898{
899 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
900 char str[20] = "";
901
902 if (size >= 20)
903 return -EINVAL;
904 if (sscanf(buf, "%s", str) != 1)
905 return -EINVAL;
906 if (!test_bit(TPDM_DS_BC, drvdata->datasets))
907 return -EPERM;
908
909 mutex_lock(&drvdata->lock);
910 if (drvdata->enable) {
911 mutex_unlock(&drvdata->lock);
912 return -EPERM;
913 }
914
915 if (!strcmp(str, "ATB")) {
916 drvdata->bc->retrieval_mode = TPDM_MODE_ATB;
917 } else if (!strcmp(str, "APB")) {
918 drvdata->bc->retrieval_mode = TPDM_MODE_APB;
919 } else {
920 mutex_unlock(&drvdata->lock);
921 return -EINVAL;
922 }
923 mutex_unlock(&drvdata->lock);
924 return size;
925}
926static DEVICE_ATTR(bc_retrieval_mode, S_IRUGO | S_IWUSR,
927 tpdm_show_bc_retrieval_mode, tpdm_store_bc_retrieval_mode);
928
929static ssize_t tpdm_store_bc_reset_counters(struct device *dev,
930 struct device_attribute *attr,
931 const char *buf,
932 size_t size)
933{
934 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
935 unsigned long val;
936
937 if (kstrtoul(buf, 16, &val))
938 return -EINVAL;
939 if (!test_bit(TPDM_DS_BC, drvdata->enable_ds))
940 return -EPERM;
941
942 mutex_lock(&drvdata->lock);
943 if (!drvdata->enable) {
944 mutex_unlock(&drvdata->lock);
945 return -EPERM;
946 }
947
948 if (val) {
949 TPDM_UNLOCK(drvdata);
950 val = tpdm_readl(drvdata, TPDM_BC_CR);
951 val = val | BIT(1);
952 tpdm_writel(drvdata, val, TPDM_BC_CR);
953 TPDM_LOCK(drvdata);
954 }
955 mutex_unlock(&drvdata->lock);
956 return size;
957}
958static DEVICE_ATTR(bc_reset_counters, S_IRUGO | S_IWUSR, NULL,
959 tpdm_store_bc_reset_counters);
960
961static ssize_t tpdm_show_bc_sat_mode(struct device *dev,
962 struct device_attribute *attr,
963 char *buf)
964{
965 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
966
967 if (!test_bit(TPDM_DS_BC, drvdata->datasets))
968 return -EPERM;
969
970 return scnprintf(buf, PAGE_SIZE, "%lx\n",
971 (unsigned long)drvdata->bc->sat_mode);
972}
973
974static ssize_t tpdm_store_bc_sat_mode(struct device *dev,
975 struct device_attribute *attr,
976 const char *buf,
977 size_t size)
978{
979 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
980 unsigned long val;
981
982 if (kstrtoul(buf, 16, &val))
983 return -EINVAL;
984 if (!test_bit(TPDM_DS_BC, drvdata->datasets))
985 return -EPERM;
986
987 mutex_lock(&drvdata->lock);
988 drvdata->bc->sat_mode = val;
989 mutex_unlock(&drvdata->lock);
990 return size;
991}
992static DEVICE_ATTR(bc_sat_mode, S_IRUGO | S_IWUSR,
993 tpdm_show_bc_sat_mode, tpdm_store_bc_sat_mode);
994
995static ssize_t tpdm_show_bc_enable_counters(struct device *dev,
996 struct device_attribute *attr,
997 char *buf)
998{
999 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1000
1001 if (!test_bit(TPDM_DS_BC, drvdata->datasets))
1002 return -EPERM;
1003
1004 return scnprintf(buf, PAGE_SIZE, "%lx\n",
1005 (unsigned long)drvdata->bc->enable_counters);
1006}
1007
1008static ssize_t tpdm_store_bc_enable_counters(struct device *dev,
1009 struct device_attribute *attr,
1010 const char *buf,
1011 size_t size)
1012{
1013 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1014 unsigned long val;
1015
1016 if (kstrtoul(buf, 16, &val))
1017 return -EINVAL;
1018 if (!test_bit(TPDM_DS_BC, drvdata->datasets))
1019 return -EPERM;
1020
1021 mutex_lock(&drvdata->lock);
1022 drvdata->bc->enable_counters = val;
1023 mutex_unlock(&drvdata->lock);
1024 return size;
1025}
1026static DEVICE_ATTR(bc_enable_counters, S_IRUGO | S_IWUSR,
1027 tpdm_show_bc_enable_counters, tpdm_store_bc_enable_counters);
1028
1029static ssize_t tpdm_show_bc_clear_counters(struct device *dev,
1030 struct device_attribute *attr,
1031 char *buf)
1032{
1033 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1034
1035 if (!test_bit(TPDM_DS_BC, drvdata->datasets))
1036 return -EPERM;
1037
1038 return scnprintf(buf, PAGE_SIZE, "%lx\n",
1039 (unsigned long)drvdata->bc->clear_counters);
1040}
1041
1042static ssize_t tpdm_store_bc_clear_counters(struct device *dev,
1043 struct device_attribute *attr,
1044 const char *buf,
1045 size_t size)
1046{
1047 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1048 unsigned long val;
1049
1050 if (kstrtoul(buf, 16, &val))
1051 return -EINVAL;
1052 if (!test_bit(TPDM_DS_BC, drvdata->datasets))
1053 return -EPERM;
1054
1055 mutex_lock(&drvdata->lock);
1056 drvdata->bc->clear_counters = val;
1057 mutex_unlock(&drvdata->lock);
1058 return size;
1059}
1060static DEVICE_ATTR(bc_clear_counters, S_IRUGO | S_IWUSR,
1061 tpdm_show_bc_clear_counters, tpdm_store_bc_clear_counters);
1062
1063static ssize_t tpdm_show_bc_enable_irq(struct device *dev,
1064 struct device_attribute *attr,
1065 char *buf)
1066{
1067 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1068
1069 if (!test_bit(TPDM_DS_BC, drvdata->datasets))
1070 return -EPERM;
1071
1072 return scnprintf(buf, PAGE_SIZE, "%lx\n",
1073 (unsigned long)drvdata->bc->enable_irq);
1074}
1075
1076static ssize_t tpdm_store_bc_enable_irq(struct device *dev,
1077 struct device_attribute *attr,
1078 const char *buf,
1079 size_t size)
1080{
1081 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1082 unsigned long val;
1083
1084 if (kstrtoul(buf, 16, &val))
1085 return -EINVAL;
1086 if (!test_bit(TPDM_DS_BC, drvdata->datasets))
1087 return -EPERM;
1088
1089 mutex_lock(&drvdata->lock);
1090 drvdata->bc->enable_irq = val;
1091 mutex_unlock(&drvdata->lock);
1092 return size;
1093}
1094static DEVICE_ATTR(bc_enable_irq, S_IRUGO | S_IWUSR,
1095 tpdm_show_bc_enable_irq, tpdm_store_bc_enable_irq);
1096
1097static ssize_t tpdm_show_bc_clear_irq(struct device *dev,
1098 struct device_attribute *attr,
1099 char *buf)
1100{
1101 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1102
1103 if (!test_bit(TPDM_DS_BC, drvdata->datasets))
1104 return -EPERM;
1105
1106 return scnprintf(buf, PAGE_SIZE, "%lx\n",
1107 (unsigned long)drvdata->bc->clear_irq);
1108}
1109
1110static ssize_t tpdm_store_bc_clear_irq(struct device *dev,
1111 struct device_attribute *attr,
1112 const char *buf,
1113 size_t size)
1114{
1115 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1116 unsigned long val;
1117
1118 if (kstrtoul(buf, 16, &val))
1119 return -EINVAL;
1120 if (!test_bit(TPDM_DS_BC, drvdata->datasets))
1121 return -EPERM;
1122
1123 mutex_lock(&drvdata->lock);
1124 drvdata->bc->clear_irq = val;
1125 mutex_unlock(&drvdata->lock);
1126 return size;
1127}
1128static DEVICE_ATTR(bc_clear_irq, S_IRUGO | S_IWUSR,
1129 tpdm_show_bc_clear_irq, tpdm_store_bc_clear_irq);
1130
1131static ssize_t tpdm_show_bc_trig_val_lo(struct device *dev,
1132 struct device_attribute *attr,
1133 char *buf)
1134{
1135 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1136 ssize_t size = 0;
1137 int i = 0;
1138
1139 if (!test_bit(TPDM_DS_BC, drvdata->datasets))
1140 return -EPERM;
1141
1142 mutex_lock(&drvdata->lock);
1143 for (i = 0; i < TPDM_BC_MAX_COUNTERS; i++)
1144 size += scnprintf(buf + size, PAGE_SIZE - size,
1145 "Index: 0x%x Value: 0x%x\n", i,
1146 drvdata->bc->trig_val_lo[i]);
1147 mutex_unlock(&drvdata->lock);
1148 return size;
1149}
1150
1151static ssize_t tpdm_store_bc_trig_val_lo(struct device *dev,
1152 struct device_attribute *attr,
1153 const char *buf,
1154 size_t size)
1155{
1156 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1157 unsigned long index, val;
1158
1159 if (sscanf(buf, "%lx %lx", &index, &val) != 2)
1160 return -EINVAL;
1161 if (!test_bit(TPDM_DS_BC, drvdata->datasets) ||
1162 index >= drvdata->bc_counters_avail ||
1163 drvdata->bc_trig_type == TPDM_SUPPORT_TYPE_NO ||
1164 (drvdata->bc_trig_type == TPDM_SUPPORT_TYPE_PARTIAL && index > 0))
1165 return -EPERM;
1166
1167 mutex_lock(&drvdata->lock);
1168 drvdata->bc->trig_val_lo[index] = val;
1169 mutex_unlock(&drvdata->lock);
1170 return size;
1171}
1172static DEVICE_ATTR(bc_trig_val_lo, S_IRUGO | S_IWUSR,
1173 tpdm_show_bc_trig_val_lo, tpdm_store_bc_trig_val_lo);
1174
1175static ssize_t tpdm_show_bc_trig_val_hi(struct device *dev,
1176 struct device_attribute *attr,
1177 char *buf)
1178{
1179 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1180 ssize_t size = 0;
1181 int i = 0;
1182
1183 if (!test_bit(TPDM_DS_BC, drvdata->datasets))
1184 return -EPERM;
1185
1186 mutex_lock(&drvdata->lock);
1187 for (i = 0; i < TPDM_BC_MAX_COUNTERS; i++)
1188 size += scnprintf(buf + size, PAGE_SIZE - size,
1189 "Index: 0x%x Value: 0x%x\n", i,
1190 drvdata->bc->trig_val_hi[i]);
1191 mutex_unlock(&drvdata->lock);
1192 return size;
1193}
1194
1195static ssize_t tpdm_store_bc_trig_val_hi(struct device *dev,
1196 struct device_attribute *attr,
1197 const char *buf,
1198 size_t size)
1199{
1200 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1201 unsigned long index, val;
1202
1203 if (sscanf(buf, "%lx %lx", &index, &val) != 2)
1204 return -EINVAL;
1205 if (!test_bit(TPDM_DS_BC, drvdata->datasets) ||
1206 index >= drvdata->bc_counters_avail ||
1207 drvdata->bc_trig_type == TPDM_SUPPORT_TYPE_NO ||
1208 (drvdata->bc_trig_type == TPDM_SUPPORT_TYPE_PARTIAL && index > 0))
1209 return -EPERM;
1210
1211 mutex_lock(&drvdata->lock);
1212 drvdata->bc->trig_val_hi[index] = val;
1213 mutex_unlock(&drvdata->lock);
1214 return size;
1215}
1216static DEVICE_ATTR(bc_trig_val_hi, S_IRUGO | S_IWUSR,
1217 tpdm_show_bc_trig_val_hi, tpdm_store_bc_trig_val_hi);
1218
1219static ssize_t tpdm_show_bc_enable_ganging(struct device *dev,
1220 struct device_attribute *attr,
1221 char *buf)
1222{
1223 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1224
1225 if (!test_bit(TPDM_DS_BC, drvdata->datasets))
1226 return -EPERM;
1227
1228 return scnprintf(buf, PAGE_SIZE, "%lx\n",
1229 (unsigned long)drvdata->bc->enable_ganging);
1230}
1231
1232static ssize_t tpdm_store_bc_enable_ganging(struct device *dev,
1233 struct device_attribute *attr,
1234 const char *buf,
1235 size_t size)
1236{
1237 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1238 unsigned long val;
1239
1240 if (kstrtoul(buf, 16, &val))
1241 return -EINVAL;
1242 if (!test_bit(TPDM_DS_BC, drvdata->datasets))
1243 return -EPERM;
1244
1245 mutex_lock(&drvdata->lock);
1246 drvdata->bc->enable_ganging = val;
1247 mutex_unlock(&drvdata->lock);
1248 return size;
1249}
1250static DEVICE_ATTR(bc_enable_ganging, S_IRUGO | S_IWUSR,
1251 tpdm_show_bc_enable_ganging, tpdm_store_bc_enable_ganging);
1252
1253static ssize_t tpdm_show_bc_overflow_val(struct device *dev,
1254 struct device_attribute *attr,
1255 char *buf)
1256{
1257 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1258 ssize_t size = 0;
1259 int i = 0;
1260
1261 if (!test_bit(TPDM_DS_BC, drvdata->datasets))
1262 return -EPERM;
1263
1264 mutex_lock(&drvdata->lock);
1265 for (i = 0; i < TPDM_BC_MAX_OVERFLOW; i++)
1266 size += scnprintf(buf + size, PAGE_SIZE - size,
1267 "Index: 0x%x Value: 0x%x\n", i,
1268 drvdata->bc->overflow_val[i]);
1269 mutex_unlock(&drvdata->lock);
1270 return size;
1271}
1272
1273static ssize_t tpdm_store_bc_overflow_val(struct device *dev,
1274 struct device_attribute *attr,
1275 const char *buf,
1276 size_t size)
1277{
1278 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1279 unsigned long index, val;
1280
1281 if (sscanf(buf, "%lx %lx", &index, &val) != 2)
1282 return -EINVAL;
1283 if (!test_bit(TPDM_DS_BC, drvdata->datasets) ||
1284 index >= TPDM_BC_MAX_OVERFLOW)
1285 return -EPERM;
1286
1287 mutex_lock(&drvdata->lock);
1288 drvdata->bc->overflow_val[index] = val;
1289 mutex_unlock(&drvdata->lock);
1290 return size;
1291}
1292static DEVICE_ATTR(bc_overflow_val, S_IRUGO | S_IWUSR,
1293 tpdm_show_bc_overflow_val, tpdm_store_bc_overflow_val);
1294
1295static ssize_t tpdm_show_bc_ovsr(struct device *dev,
1296 struct device_attribute *attr,
1297 char *buf)
1298{
1299 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1300 unsigned long val;
1301
1302 if (!test_bit(TPDM_DS_BC, drvdata->enable_ds))
1303 return -EPERM;
1304
1305 mutex_lock(&drvdata->lock);
1306 if (!drvdata->enable) {
1307 mutex_unlock(&drvdata->lock);
1308 return -EPERM;
1309 }
1310
1311 TPDM_UNLOCK(drvdata);
1312 val = tpdm_readl(drvdata, TPDM_BC_OVSR);
1313 TPDM_LOCK(drvdata);
1314 mutex_unlock(&drvdata->lock);
1315 return scnprintf(buf, PAGE_SIZE, "%lx\n", val);
1316}
1317
1318static ssize_t tpdm_store_bc_ovsr(struct device *dev,
1319 struct device_attribute *attr,
1320 const char *buf,
1321 size_t size)
1322{
1323 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1324 unsigned long val;
1325
1326 if (kstrtoul(buf, 16, &val))
1327 return -EINVAL;
1328 if (!test_bit(TPDM_DS_BC, drvdata->enable_ds))
1329 return -EPERM;
1330
1331 mutex_lock(&drvdata->lock);
1332 if (!drvdata->enable) {
1333 mutex_unlock(&drvdata->lock);
1334 return -EPERM;
1335 }
1336
1337 if (val) {
1338 TPDM_UNLOCK(drvdata);
1339 tpdm_writel(drvdata, val, TPDM_BC_OVSR);
1340 TPDM_LOCK(drvdata);
1341 }
1342 mutex_unlock(&drvdata->lock);
1343 return size;
1344}
1345static DEVICE_ATTR(bc_ovsr, S_IRUGO | S_IWUSR,
1346 tpdm_show_bc_ovsr, tpdm_store_bc_ovsr);
1347
1348static ssize_t tpdm_show_bc_counter_sel(struct device *dev,
1349 struct device_attribute *attr,
1350 char *buf)
1351{
1352 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1353 unsigned long val;
1354
1355 if (!test_bit(TPDM_DS_BC, drvdata->enable_ds))
1356 return -EPERM;
1357
1358 mutex_lock(&drvdata->lock);
1359 if (!drvdata->enable) {
1360 mutex_unlock(&drvdata->lock);
1361 return -EPERM;
1362 }
1363
1364 TPDM_UNLOCK(drvdata);
1365 val = tpdm_readl(drvdata, TPDM_BC_SELR);
1366 TPDM_LOCK(drvdata);
1367 mutex_unlock(&drvdata->lock);
1368 return scnprintf(buf, PAGE_SIZE, "%lx\n", val);
1369}
1370
1371static ssize_t tpdm_store_bc_counter_sel(struct device *dev,
1372 struct device_attribute *attr,
1373 const char *buf,
1374 size_t size)
1375{
1376 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1377 unsigned long val;
1378
1379 if (kstrtoul(buf, 16, &val))
1380 return -EINVAL;
1381 if (!test_bit(TPDM_DS_BC, drvdata->enable_ds))
1382 return -EPERM;
1383
1384 mutex_lock(&drvdata->lock);
1385 if (!drvdata->enable || val >= drvdata->bc_counters_avail) {
1386 mutex_unlock(&drvdata->lock);
1387 return -EPERM;
1388 }
1389
1390 TPDM_UNLOCK(drvdata);
1391 tpdm_writel(drvdata, val, TPDM_BC_SELR);
1392 TPDM_LOCK(drvdata);
1393 mutex_unlock(&drvdata->lock);
1394 return size;
1395}
1396static DEVICE_ATTR(bc_counter_sel, S_IRUGO | S_IWUSR,
1397 tpdm_show_bc_counter_sel, tpdm_store_bc_counter_sel);
1398
1399static ssize_t tpdm_show_bc_count_val_lo(struct device *dev,
1400 struct device_attribute *attr,
1401 char *buf)
1402{
1403 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1404 unsigned long val;
1405
1406 if (!test_bit(TPDM_DS_BC, drvdata->enable_ds))
1407 return -EPERM;
1408
1409 mutex_lock(&drvdata->lock);
1410 if (!drvdata->enable) {
1411 mutex_unlock(&drvdata->lock);
1412 return -EPERM;
1413 }
1414
1415 TPDM_UNLOCK(drvdata);
1416 val = tpdm_readl(drvdata, TPDM_BC_CNTR_LO);
1417 TPDM_LOCK(drvdata);
1418 mutex_unlock(&drvdata->lock);
1419 return scnprintf(buf, PAGE_SIZE, "%lx\n", val);
1420}
1421
1422static ssize_t tpdm_store_bc_count_val_lo(struct device *dev,
1423 struct device_attribute *attr,
1424 const char *buf,
1425 size_t size)
1426{
1427 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1428 unsigned long val, select;
1429
1430 if (kstrtoul(buf, 16, &val))
1431 return -EINVAL;
1432 if (!test_bit(TPDM_DS_BC, drvdata->enable_ds))
1433 return -EPERM;
1434
1435 mutex_lock(&drvdata->lock);
1436 if (!drvdata->enable) {
1437 mutex_unlock(&drvdata->lock);
1438 return -EPERM;
1439 }
1440
1441 if (val) {
1442 TPDM_UNLOCK(drvdata);
1443 select = tpdm_readl(drvdata, TPDM_BC_SELR);
1444
1445 /* Check if selected counter is disabled */
1446 if (BVAL(tpdm_readl(drvdata, TPDM_BC_CNTENSET), select)) {
1447 mutex_unlock(&drvdata->lock);
1448 return -EPERM;
1449 }
1450
1451 tpdm_writel(drvdata, val, TPDM_BC_CNTR_LO);
1452 TPDM_LOCK(drvdata);
1453 }
1454 mutex_unlock(&drvdata->lock);
1455 return size;
1456}
1457static DEVICE_ATTR(bc_count_val_lo, S_IRUGO | S_IWUSR,
1458 tpdm_show_bc_count_val_lo, tpdm_store_bc_count_val_lo);
1459
1460static ssize_t tpdm_show_bc_count_val_hi(struct device *dev,
1461 struct device_attribute *attr,
1462 char *buf)
1463{
1464 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1465 unsigned long val;
1466
1467 if (!test_bit(TPDM_DS_BC, drvdata->enable_ds))
1468 return -EPERM;
1469
1470 mutex_lock(&drvdata->lock);
1471 if (!drvdata->enable) {
1472 mutex_unlock(&drvdata->lock);
1473 return -EPERM;
1474 }
1475
1476 TPDM_UNLOCK(drvdata);
1477 val = tpdm_readl(drvdata, TPDM_BC_CNTR_HI);
1478 TPDM_LOCK(drvdata);
1479 mutex_unlock(&drvdata->lock);
1480 return scnprintf(buf, PAGE_SIZE, "%lx\n", val);
1481}
1482
1483static ssize_t tpdm_store_bc_count_val_hi(struct device *dev,
1484 struct device_attribute *attr,
1485 const char *buf,
1486 size_t size)
1487{
1488 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1489 unsigned long val, select;
1490
1491 if (kstrtoul(buf, 16, &val))
1492 return -EINVAL;
1493 if (!test_bit(TPDM_DS_BC, drvdata->enable_ds))
1494 return -EPERM;
1495
1496 mutex_lock(&drvdata->lock);
1497 if (!drvdata->enable) {
1498 mutex_unlock(&drvdata->lock);
1499 return -EPERM;
1500 }
1501
1502 if (val) {
1503 TPDM_UNLOCK(drvdata);
1504 select = tpdm_readl(drvdata, TPDM_BC_SELR);
1505
1506 /* Check if selected counter is disabled */
1507 if (BVAL(tpdm_readl(drvdata, TPDM_BC_CNTENSET), select)) {
1508 mutex_unlock(&drvdata->lock);
1509 return -EPERM;
1510 }
1511
1512 tpdm_writel(drvdata, val, TPDM_BC_CNTR_HI);
1513 TPDM_LOCK(drvdata);
1514 }
1515 mutex_unlock(&drvdata->lock);
1516 return size;
1517}
1518static DEVICE_ATTR(bc_count_val_hi, S_IRUGO | S_IWUSR,
1519 tpdm_show_bc_count_val_hi, tpdm_store_bc_count_val_hi);
1520
1521static ssize_t tpdm_show_bc_shadow_val_lo(struct device *dev,
1522 struct device_attribute *attr,
1523 char *buf)
1524{
1525 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1526 ssize_t size = 0;
1527 int i = 0;
1528
1529 if (!test_bit(TPDM_DS_BC, drvdata->enable_ds))
1530 return -EPERM;
1531
1532 mutex_lock(&drvdata->lock);
1533 if (!drvdata->enable) {
1534 mutex_unlock(&drvdata->lock);
1535 return -EPERM;
1536 }
1537
1538 TPDM_UNLOCK(drvdata);
1539 for (i = 0; i < drvdata->bc_counters_avail; i++) {
1540 size += scnprintf(buf + size, PAGE_SIZE - size,
1541 "Index: 0x%x Value: 0x%x\n", i,
1542 tpdm_readl(drvdata, TPDM_BC_SHADOW_LO(i)));
1543 }
1544 TPDM_LOCK(drvdata);
1545 mutex_unlock(&drvdata->lock);
1546 return size;
1547}
1548static DEVICE_ATTR(bc_shadow_val_lo, S_IRUGO | S_IWUSR,
1549 tpdm_show_bc_shadow_val_lo, NULL);
1550
1551static ssize_t tpdm_show_bc_shadow_val_hi(struct device *dev,
1552 struct device_attribute *attr,
1553 char *buf)
1554{
1555 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1556 ssize_t size = 0;
1557 int i = 0;
1558
1559 if (!test_bit(TPDM_DS_BC, drvdata->enable_ds))
1560 return -EPERM;
1561
1562 mutex_lock(&drvdata->lock);
1563 if (!drvdata->enable) {
1564 mutex_unlock(&drvdata->lock);
1565 return -EPERM;
1566 }
1567
1568 TPDM_UNLOCK(drvdata);
1569 for (i = 0; i < drvdata->bc_counters_avail; i++)
1570 size += scnprintf(buf + size, PAGE_SIZE - size,
1571 "Index: 0x%x Value: 0x%x\n", i,
1572 tpdm_readl(drvdata, TPDM_BC_SHADOW_HI(i)));
1573 TPDM_LOCK(drvdata);
1574 mutex_unlock(&drvdata->lock);
1575 return size;
1576}
1577static DEVICE_ATTR(bc_shadow_val_hi, S_IRUGO | S_IWUSR,
1578 tpdm_show_bc_shadow_val_hi, NULL);
1579
1580static ssize_t tpdm_show_bc_sw_inc(struct device *dev,
1581 struct device_attribute *attr,
1582 char *buf)
1583{
1584 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1585 unsigned long val;
1586
1587 if (!test_bit(TPDM_DS_BC, drvdata->enable_ds))
1588 return -EPERM;
1589
1590 mutex_lock(&drvdata->lock);
1591 if (!drvdata->enable) {
1592 mutex_unlock(&drvdata->lock);
1593 return -EPERM;
1594 }
1595
1596 TPDM_UNLOCK(drvdata);
1597 val = tpdm_readl(drvdata, TPDM_BC_SWINC);
1598 TPDM_LOCK(drvdata);
1599 mutex_unlock(&drvdata->lock);
1600 return scnprintf(buf, PAGE_SIZE, "%lx\n", val);
1601}
1602
1603static ssize_t tpdm_store_bc_sw_inc(struct device *dev,
1604 struct device_attribute *attr,
1605 const char *buf,
1606 size_t size)
1607{
1608 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1609 unsigned long val;
1610
1611 if (kstrtoul(buf, 16, &val))
1612 return -EINVAL;
1613 if (!test_bit(TPDM_DS_BC, drvdata->enable_ds))
1614 return -EPERM;
1615
1616 mutex_lock(&drvdata->lock);
1617 if (!drvdata->enable) {
1618 mutex_unlock(&drvdata->lock);
1619 return -EPERM;
1620 }
1621
1622 if (val) {
1623 TPDM_UNLOCK(drvdata);
1624 tpdm_writel(drvdata, val, TPDM_BC_SWINC);
1625 TPDM_LOCK(drvdata);
1626 }
1627 mutex_unlock(&drvdata->lock);
1628 return size;
1629}
1630static DEVICE_ATTR(bc_sw_inc, S_IRUGO | S_IWUSR,
1631 tpdm_show_bc_sw_inc, tpdm_store_bc_sw_inc);
1632
1633static ssize_t tpdm_store_bc_msr(struct device *dev,
1634 struct device_attribute *attr,
1635 const char *buf,
1636 size_t size)
1637{
1638 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1639 unsigned int num, val;
1640 int nval;
1641
1642 if (!drvdata->msr_support)
1643 return -EINVAL;
1644
1645 if (!test_bit(TPDM_DS_BC, drvdata->datasets))
1646 return -EPERM;
1647
1648 nval = sscanf(buf, "%u %x", &num, &val);
1649 if (nval != 2)
1650 return -EINVAL;
1651
1652 if (num >= TPDM_BC_MAX_MSR)
1653 return -EINVAL;
1654
1655 mutex_lock(&drvdata->lock);
1656 drvdata->bc->msr[num] = val;
1657 mutex_unlock(&drvdata->lock);
1658 return size;
1659}
1660static DEVICE_ATTR(bc_msr, S_IWUSR, NULL, tpdm_store_bc_msr);
1661
1662static ssize_t tpdm_show_tc_capture_mode(struct device *dev,
1663 struct device_attribute *attr,
1664 char *buf)
1665{
1666 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1667
1668 if (!test_bit(TPDM_DS_TC, drvdata->datasets))
1669 return -EPERM;
1670
1671 return scnprintf(buf, PAGE_SIZE, "%s\n",
1672 drvdata->tc->capture_mode == TPDM_MODE_ATB ?
1673 "ATB" : "APB");
1674}
1675
1676static ssize_t tpdm_store_tc_capture_mode(struct device *dev,
1677 struct device_attribute *attr,
1678 const char *buf,
1679 size_t size)
1680{
1681 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1682 char str[20] = "";
1683 uint32_t val;
1684
1685 if (size >= 20)
1686 return -EINVAL;
1687 if (sscanf(buf, "%s", str) != 1)
1688 return -EINVAL;
1689 if (!test_bit(TPDM_DS_TC, drvdata->enable_ds))
1690 return -EPERM;
1691
1692 mutex_lock(&drvdata->lock);
1693 if (!drvdata->enable) {
1694 mutex_unlock(&drvdata->lock);
1695 return -EPERM;
1696 }
1697
1698 if (!strcmp(str, "ATB")) {
1699 drvdata->tc->capture_mode = TPDM_MODE_ATB;
1700 } else if (!strcmp(str, "APB") &&
1701 drvdata->tc->retrieval_mode == TPDM_MODE_APB) {
1702
1703 TPDM_UNLOCK(drvdata);
1704 val = tpdm_readl(drvdata, TPDM_TC_CR);
1705 val = val | BIT(3);
1706 tpdm_writel(drvdata, val, TPDM_TC_CR);
1707 TPDM_LOCK(drvdata);
1708
1709 drvdata->tc->capture_mode = TPDM_MODE_APB;
1710 } else {
1711 mutex_unlock(&drvdata->lock);
1712 return -EINVAL;
1713 }
1714 mutex_unlock(&drvdata->lock);
1715 return size;
1716}
1717static DEVICE_ATTR(tc_capture_mode, S_IRUGO | S_IWUSR,
1718 tpdm_show_tc_capture_mode, tpdm_store_tc_capture_mode);
1719
1720static ssize_t tpdm_show_tc_retrieval_mode(struct device *dev,
1721 struct device_attribute *attr,
1722 char *buf)
1723{
1724 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1725
1726 if (!test_bit(TPDM_DS_TC, drvdata->datasets))
1727 return -EPERM;
1728
1729 return scnprintf(buf, PAGE_SIZE, "%s\n",
1730 drvdata->tc->retrieval_mode == TPDM_MODE_ATB ?
1731 "ATB" : "APB");
1732}
1733
1734static ssize_t tpdm_store_tc_retrieval_mode(struct device *dev,
1735 struct device_attribute *attr,
1736 const char *buf,
1737 size_t size)
1738{
1739 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1740 char str[20] = "";
1741
1742 if (size >= 20)
1743 return -EINVAL;
1744 if (sscanf(buf, "%s", str) != 1)
1745 return -EINVAL;
1746 if (!test_bit(TPDM_DS_TC, drvdata->datasets))
1747 return -EPERM;
1748
1749 mutex_lock(&drvdata->lock);
1750 if (drvdata->enable) {
1751 mutex_unlock(&drvdata->lock);
1752 return -EPERM;
1753 }
1754
1755 if (!strcmp(str, "ATB")) {
1756 drvdata->tc->retrieval_mode = TPDM_MODE_ATB;
1757 } else if (!strcmp(str, "APB")) {
1758 drvdata->tc->retrieval_mode = TPDM_MODE_APB;
1759 } else {
1760 mutex_unlock(&drvdata->lock);
1761 return -EINVAL;
1762 }
1763 mutex_unlock(&drvdata->lock);
1764 return size;
1765}
1766static DEVICE_ATTR(tc_retrieval_mode, S_IRUGO | S_IWUSR,
1767 tpdm_show_tc_retrieval_mode, tpdm_store_tc_retrieval_mode);
1768
1769static ssize_t tpdm_store_tc_reset_counters(struct device *dev,
1770 struct device_attribute *attr,
1771 const char *buf,
1772 size_t size)
1773{
1774 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1775 unsigned long val;
1776
1777 if (kstrtoul(buf, 16, &val))
1778 return -EINVAL;
1779 if (!test_bit(TPDM_DS_TC, drvdata->datasets))
1780 return -EPERM;
1781
1782 mutex_lock(&drvdata->lock);
1783 if (!drvdata->enable) {
1784 mutex_unlock(&drvdata->lock);
1785 return -EPERM;
1786 }
1787
1788 if (val) {
1789 TPDM_UNLOCK(drvdata);
1790 val = tpdm_readl(drvdata, TPDM_TC_CR);
1791 val = val | BIT(1);
1792 tpdm_writel(drvdata, val, TPDM_TC_CR);
1793 TPDM_LOCK(drvdata);
1794 }
1795 mutex_unlock(&drvdata->lock);
1796 return size;
1797}
1798static DEVICE_ATTR(tc_reset_counters, S_IRUGO | S_IWUSR, NULL,
1799 tpdm_store_tc_reset_counters);
1800
1801static ssize_t tpdm_show_tc_sat_mode(struct device *dev,
1802 struct device_attribute *attr,
1803 char *buf)
1804{
1805 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1806
1807 if (!test_bit(TPDM_DS_TC, drvdata->datasets))
1808 return -EPERM;
1809
1810 return scnprintf(buf, PAGE_SIZE, "%u\n",
1811 (unsigned int)drvdata->tc->sat_mode);
1812}
1813
1814static ssize_t tpdm_store_tc_sat_mode(struct device *dev,
1815 struct device_attribute *attr,
1816 const char *buf,
1817 size_t size)
1818{
1819 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1820 unsigned long val;
1821
1822 if (kstrtoul(buf, 16, &val))
1823 return -EINVAL;
1824 if (!test_bit(TPDM_DS_TC, drvdata->datasets))
1825 return -EPERM;
1826
1827 mutex_lock(&drvdata->lock);
1828 if (val)
1829 drvdata->tc->sat_mode = true;
1830 else
1831 drvdata->tc->sat_mode = false;
1832 mutex_unlock(&drvdata->lock);
1833 return size;
1834}
1835static DEVICE_ATTR(tc_sat_mode, S_IRUGO | S_IWUSR,
1836 tpdm_show_tc_sat_mode, tpdm_store_tc_sat_mode);
1837
1838static ssize_t tpdm_show_tc_enable_counters(struct device *dev,
1839 struct device_attribute *attr,
1840 char *buf)
1841{
1842 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1843
1844 if (!test_bit(TPDM_DS_TC, drvdata->datasets))
1845 return -EPERM;
1846
1847 return scnprintf(buf, PAGE_SIZE, "%lx\n",
1848 (unsigned long)drvdata->tc->enable_counters);
1849}
1850
1851static ssize_t tpdm_store_tc_enable_counters(struct device *dev,
1852 struct device_attribute *attr,
1853 const char *buf,
1854 size_t size)
1855{
1856 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1857 unsigned long val;
1858
1859 if (kstrtoul(buf, 16, &val))
1860 return -EINVAL;
1861 if (!test_bit(TPDM_DS_TC, drvdata->datasets))
1862 return -EPERM;
1863 if (val >> drvdata->tc_counters_avail)
1864 return -EPERM;
1865
1866 mutex_lock(&drvdata->lock);
1867 drvdata->tc->enable_counters = val;
1868 mutex_unlock(&drvdata->lock);
1869 return size;
1870}
1871static DEVICE_ATTR(tc_enable_counters, S_IRUGO | S_IWUSR,
1872 tpdm_show_tc_enable_counters, tpdm_store_tc_enable_counters);
1873
1874static ssize_t tpdm_show_tc_clear_counters(struct device *dev,
1875 struct device_attribute *attr,
1876 char *buf)
1877{
1878 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1879
1880 if (!test_bit(TPDM_DS_TC, drvdata->datasets))
1881 return -EPERM;
1882
1883 return scnprintf(buf, PAGE_SIZE, "%lx\n",
1884 (unsigned long)drvdata->tc->clear_counters);
1885}
1886
1887static ssize_t tpdm_store_tc_clear_counters(struct device *dev,
1888 struct device_attribute *attr,
1889 const char *buf,
1890 size_t size)
1891{
1892 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1893 unsigned long val;
1894
1895 if (kstrtoul(buf, 16, &val))
1896 return -EINVAL;
1897 if (!test_bit(TPDM_DS_TC, drvdata->datasets))
1898 return -EPERM;
1899 if (val >> drvdata->tc_counters_avail)
1900 return -EPERM;
1901
1902 mutex_lock(&drvdata->lock);
1903 drvdata->tc->clear_counters = val;
1904 mutex_unlock(&drvdata->lock);
1905 return size;
1906}
1907static DEVICE_ATTR(tc_clear_counters, S_IRUGO | S_IWUSR,
1908 tpdm_show_tc_clear_counters, tpdm_store_tc_clear_counters);
1909
1910static ssize_t tpdm_show_tc_enable_irq(struct device *dev,
1911 struct device_attribute *attr,
1912 char *buf)
1913{
1914 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1915
1916 if (!test_bit(TPDM_DS_TC, drvdata->datasets))
1917 return -EPERM;
1918
1919 return scnprintf(buf, PAGE_SIZE, "%lx\n",
1920 (unsigned long)drvdata->tc->enable_irq);
1921}
1922
1923static ssize_t tpdm_store_tc_enable_irq(struct device *dev,
1924 struct device_attribute *attr,
1925 const char *buf,
1926 size_t size)
1927{
1928 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1929 unsigned long val;
1930
1931 if (kstrtoul(buf, 16, &val))
1932 return -EINVAL;
1933 if (!test_bit(TPDM_DS_TC, drvdata->datasets))
1934 return -EPERM;
1935
1936 mutex_lock(&drvdata->lock);
1937 drvdata->tc->enable_irq = val;
1938 mutex_unlock(&drvdata->lock);
1939 return size;
1940}
1941static DEVICE_ATTR(tc_enable_irq, S_IRUGO | S_IWUSR,
1942 tpdm_show_tc_enable_irq, tpdm_store_tc_enable_irq);
1943
1944static ssize_t tpdm_show_tc_clear_irq(struct device *dev,
1945 struct device_attribute *attr,
1946 char *buf)
1947{
1948 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1949
1950 if (!test_bit(TPDM_DS_TC, drvdata->datasets))
1951 return -EPERM;
1952
1953 return scnprintf(buf, PAGE_SIZE, "%lx\n",
1954 (unsigned long)drvdata->tc->clear_irq);
1955}
1956
1957static ssize_t tpdm_store_tc_clear_irq(struct device *dev,
1958 struct device_attribute *attr,
1959 const char *buf,
1960 size_t size)
1961{
1962 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1963 unsigned long val;
1964
1965 if (kstrtoul(buf, 16, &val))
1966 return -EINVAL;
1967 if (!test_bit(TPDM_DS_TC, drvdata->datasets))
1968 return -EPERM;
1969
1970 mutex_lock(&drvdata->lock);
1971 drvdata->tc->clear_irq = val;
1972 mutex_unlock(&drvdata->lock);
1973 return size;
1974}
1975static DEVICE_ATTR(tc_clear_irq, S_IRUGO | S_IWUSR,
1976 tpdm_show_tc_clear_irq, tpdm_store_tc_clear_irq);
1977
1978static ssize_t tpdm_show_tc_trig_sel(struct device *dev,
1979 struct device_attribute *attr,
1980 char *buf)
1981{
1982 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1983 ssize_t size = 0;
1984 int i = 0;
1985
1986 if (!test_bit(TPDM_DS_TC, drvdata->datasets))
1987 return -EPERM;
1988
1989 mutex_lock(&drvdata->lock);
1990 for (i = 0; i < TPDM_TC_MAX_TRIG; i++) {
1991 size += scnprintf(buf + size, PAGE_SIZE - size,
1992 "Index: 0x%x Value: 0x%x\n", i,
1993 drvdata->tc->trig_sel[i]);
1994 }
1995 mutex_unlock(&drvdata->lock);
1996 return size;
1997}
1998
1999static ssize_t tpdm_store_tc_trig_sel(struct device *dev,
2000 struct device_attribute *attr,
2001 const char *buf,
2002 size_t size)
2003{
2004 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2005 unsigned long index, val;
2006
2007 if (sscanf(buf, "%lx %lx", &index, &val) != 2)
2008 return -EINVAL;
2009 if (!test_bit(TPDM_DS_TC, drvdata->datasets) ||
2010 index >= TPDM_TC_MAX_TRIG ||
2011 drvdata->tc_trig_type == TPDM_SUPPORT_TYPE_NO ||
2012 (drvdata->tc_trig_type == TPDM_SUPPORT_TYPE_PARTIAL && index > 0))
2013 return -EPERM;
2014
2015 mutex_lock(&drvdata->lock);
2016 drvdata->tc->trig_sel[index] = val;
2017 mutex_unlock(&drvdata->lock);
2018 return size;
2019}
2020static DEVICE_ATTR(tc_trig_sel, S_IRUGO | S_IWUSR,
2021 tpdm_show_tc_trig_sel, tpdm_store_tc_trig_sel);
2022
2023static ssize_t tpdm_show_tc_trig_val_lo(struct device *dev,
2024 struct device_attribute *attr,
2025 char *buf)
2026{
2027 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2028 ssize_t size = 0;
2029 int i = 0;
2030
2031 if (!test_bit(TPDM_DS_TC, drvdata->datasets))
2032 return -EPERM;
2033
2034 mutex_lock(&drvdata->lock);
2035 for (i = 0; i < TPDM_TC_MAX_TRIG; i++) {
2036 size += scnprintf(buf + size, PAGE_SIZE - size,
2037 "Index: 0x%x Value: 0x%x\n", i,
2038 drvdata->tc->trig_val_lo[i]);
2039 }
2040 mutex_unlock(&drvdata->lock);
2041 return size;
2042}
2043
2044static ssize_t tpdm_store_tc_trig_val_lo(struct device *dev,
2045 struct device_attribute *attr,
2046 const char *buf,
2047 size_t size)
2048{
2049 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2050 unsigned long index, val;
2051
2052 if (sscanf(buf, "%lx %lx", &index, &val) != 2)
2053 return -EINVAL;
2054 if (!test_bit(TPDM_DS_TC, drvdata->datasets) ||
2055 index >= TPDM_TC_MAX_TRIG ||
2056 drvdata->tc_trig_type == TPDM_SUPPORT_TYPE_NO ||
2057 (drvdata->tc_trig_type == TPDM_SUPPORT_TYPE_PARTIAL && index > 0))
2058 return -EPERM;
2059
2060 mutex_lock(&drvdata->lock);
2061 drvdata->tc->trig_val_lo[index] = val;
2062 mutex_unlock(&drvdata->lock);
2063 return size;
2064}
2065static DEVICE_ATTR(tc_trig_val_lo, S_IRUGO | S_IWUSR,
2066 tpdm_show_tc_trig_val_lo, tpdm_store_tc_trig_val_lo);
2067
2068static ssize_t tpdm_show_tc_trig_val_hi(struct device *dev,
2069 struct device_attribute *attr,
2070 char *buf)
2071{
2072 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2073 ssize_t size = 0;
2074 int i = 0;
2075
2076 if (!test_bit(TPDM_DS_TC, drvdata->datasets))
2077 return -EPERM;
2078
2079 mutex_lock(&drvdata->lock);
2080 for (i = 0; i < TPDM_TC_MAX_TRIG; i++) {
2081 size += scnprintf(buf + size, PAGE_SIZE - size,
2082 "Index: 0x%x Value: 0x%x\n", i,
2083 drvdata->tc->trig_val_hi[i]);
2084 }
2085 mutex_unlock(&drvdata->lock);
2086 return size;
2087}
2088
2089static ssize_t tpdm_store_tc_trig_val_hi(struct device *dev,
2090 struct device_attribute *attr,
2091 const char *buf,
2092 size_t size)
2093{
2094 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2095 unsigned long index, val;
2096
2097 if (sscanf(buf, "%lx %lx", &index, &val) != 2)
2098 return -EINVAL;
2099 if (!test_bit(TPDM_DS_TC, drvdata->datasets) ||
2100 index >= TPDM_TC_MAX_TRIG ||
2101 drvdata->tc_trig_type == TPDM_SUPPORT_TYPE_NO ||
2102 (drvdata->tc_trig_type == TPDM_SUPPORT_TYPE_PARTIAL && index > 0))
2103 return -EPERM;
2104
2105 mutex_lock(&drvdata->lock);
2106 drvdata->tc->trig_val_hi[index] = val;
2107 mutex_unlock(&drvdata->lock);
2108 return size;
2109}
2110static DEVICE_ATTR(tc_trig_val_hi, S_IRUGO | S_IWUSR,
2111 tpdm_show_tc_trig_val_hi, tpdm_store_tc_trig_val_hi);
2112
2113static ssize_t tpdm_show_tc_ovsr_gp(struct device *dev,
2114 struct device_attribute *attr,
2115 char *buf)
2116{
2117 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2118 unsigned long val;
2119
2120 if (!test_bit(TPDM_DS_TC, drvdata->datasets))
2121 return -EPERM;
2122
2123 mutex_lock(&drvdata->lock);
2124 if (!drvdata->enable) {
2125 mutex_unlock(&drvdata->lock);
2126 return -EPERM;
2127 }
2128
2129 TPDM_UNLOCK(drvdata);
2130 val = tpdm_readl(drvdata, TPDM_TC_OVSR_GP);
2131 TPDM_LOCK(drvdata);
2132 mutex_unlock(&drvdata->lock);
2133 return scnprintf(buf, PAGE_SIZE, "%lx\n", val);
2134}
2135
2136static ssize_t tpdm_store_tc_ovsr_gp(struct device *dev,
2137 struct device_attribute *attr,
2138 const char *buf,
2139 size_t size)
2140{
2141 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2142 unsigned long val;
2143
2144 if (kstrtoul(buf, 16, &val))
2145 return -EINVAL;
2146 if (!test_bit(TPDM_DS_TC, drvdata->enable_ds))
2147 return -EPERM;
2148
2149 mutex_lock(&drvdata->lock);
2150 if (!drvdata->enable) {
2151 mutex_unlock(&drvdata->lock);
2152 return -EPERM;
2153 }
2154
2155 if (val) {
2156 TPDM_UNLOCK(drvdata);
2157 tpdm_writel(drvdata, val, TPDM_TC_OVSR_GP);
2158 TPDM_LOCK(drvdata);
2159 }
2160 mutex_unlock(&drvdata->lock);
2161 return size;
2162}
2163static DEVICE_ATTR(tc_ovsr_gp, S_IRUGO | S_IWUSR,
2164 tpdm_show_tc_ovsr_gp, tpdm_store_tc_ovsr_gp);
2165
2166static ssize_t tpdm_show_tc_ovsr_impl(struct device *dev,
2167 struct device_attribute *attr,
2168 char *buf)
2169{
2170 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2171 unsigned long val;
2172
2173 if (!test_bit(TPDM_DS_TC, drvdata->enable_ds))
2174 return -EPERM;
2175
2176 mutex_lock(&drvdata->lock);
2177 if (!drvdata->enable) {
2178 mutex_unlock(&drvdata->lock);
2179 return -EPERM;
2180 }
2181
2182 TPDM_UNLOCK(drvdata);
2183 val = tpdm_readl(drvdata, TPDM_TC_OVSR_IMPL);
2184 TPDM_LOCK(drvdata);
2185 mutex_unlock(&drvdata->lock);
2186 return scnprintf(buf, PAGE_SIZE, "%lx\n", val);
2187}
2188
2189static ssize_t tpdm_store_tc_ovsr_impl(struct device *dev,
2190 struct device_attribute *attr,
2191 const char *buf,
2192 size_t size)
2193{
2194 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2195 unsigned long val;
2196
2197 if (kstrtoul(buf, 16, &val))
2198 return -EINVAL;
2199 if (!test_bit(TPDM_DS_TC, drvdata->enable_ds))
2200 return -EPERM;
2201
2202 mutex_lock(&drvdata->lock);
2203 if (!drvdata->enable) {
2204 mutex_unlock(&drvdata->lock);
2205 return -EPERM;
2206 }
2207
2208 if (val) {
2209 TPDM_UNLOCK(drvdata);
2210 tpdm_writel(drvdata, val, TPDM_TC_OVSR_IMPL);
2211 TPDM_LOCK(drvdata);
2212 }
2213 mutex_unlock(&drvdata->lock);
2214 return size;
2215}
2216static DEVICE_ATTR(tc_ovsr_impl, S_IRUGO | S_IWUSR,
2217 tpdm_show_tc_ovsr_impl, tpdm_store_tc_ovsr_impl);
2218
2219static ssize_t tpdm_show_tc_counter_sel(struct device *dev,
2220 struct device_attribute *attr,
2221 char *buf)
2222{
2223 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2224 unsigned long val;
2225
2226 if (!test_bit(TPDM_DS_TC, drvdata->enable_ds))
2227 return -EPERM;
2228
2229 mutex_lock(&drvdata->lock);
2230 if (!drvdata->enable) {
2231 mutex_unlock(&drvdata->lock);
2232 return -EPERM;
2233 }
2234
2235 TPDM_UNLOCK(drvdata);
2236 val = tpdm_readl(drvdata, TPDM_TC_SELR);
2237 TPDM_LOCK(drvdata);
2238 mutex_unlock(&drvdata->lock);
2239 return scnprintf(buf, PAGE_SIZE, "%lx\n", val);
2240}
2241
2242static ssize_t tpdm_store_tc_counter_sel(struct device *dev,
2243 struct device_attribute *attr,
2244 const char *buf,
2245 size_t size)
2246{
2247 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2248 unsigned long val;
2249
2250 if (kstrtoul(buf, 16, &val))
2251 return -EINVAL;
2252 if (!test_bit(TPDM_DS_TC, drvdata->enable_ds))
2253 return -EPERM;
2254
2255 mutex_lock(&drvdata->lock);
2256 if (!drvdata->enable) {
2257 mutex_unlock(&drvdata->lock);
2258 return -EPERM;
2259 }
2260
2261 TPDM_UNLOCK(drvdata);
2262 tpdm_writel(drvdata, val, TPDM_TC_SELR);
2263 TPDM_LOCK(drvdata);
2264 mutex_unlock(&drvdata->lock);
2265 return size;
2266}
2267static DEVICE_ATTR(tc_counter_sel, S_IRUGO | S_IWUSR,
2268 tpdm_show_tc_counter_sel, tpdm_store_tc_counter_sel);
2269
2270static ssize_t tpdm_show_tc_count_val_lo(struct device *dev,
2271 struct device_attribute *attr,
2272 char *buf)
2273{
2274 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2275 unsigned long val;
2276
2277 if (!test_bit(TPDM_DS_TC, drvdata->enable_ds))
2278 return -EPERM;
2279
2280 mutex_lock(&drvdata->lock);
2281 if (!drvdata->enable) {
2282 mutex_unlock(&drvdata->lock);
2283 return -EPERM;
2284 }
2285
2286 TPDM_UNLOCK(drvdata);
2287 val = tpdm_readl(drvdata, TPDM_TC_CNTR_LO);
2288 TPDM_LOCK(drvdata);
2289 mutex_unlock(&drvdata->lock);
2290 return scnprintf(buf, PAGE_SIZE, "%lx\n", val);
2291}
2292
2293static ssize_t tpdm_store_tc_count_val_lo(struct device *dev,
2294 struct device_attribute *attr,
2295 const char *buf,
2296 size_t size)
2297{
2298 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2299 unsigned long val, select;
2300
2301 if (kstrtoul(buf, 16, &val))
2302 return -EINVAL;
2303 if (!test_bit(TPDM_DS_TC, drvdata->enable_ds))
2304 return -EPERM;
2305
2306 mutex_lock(&drvdata->lock);
2307 if (!drvdata->enable) {
2308 mutex_unlock(&drvdata->lock);
2309 return -EPERM;
2310 }
2311
2312 if (val) {
2313 TPDM_UNLOCK(drvdata);
2314 select = tpdm_readl(drvdata, TPDM_TC_SELR);
2315 select = (select >> 11) & 0x3;
2316
2317 /* Check if selected counter is disabled */
2318 if (BVAL(tpdm_readl(drvdata, TPDM_TC_CNTENSET), select)) {
2319 mutex_unlock(&drvdata->lock);
2320 return -EPERM;
2321 }
2322
2323 tpdm_writel(drvdata, val, TPDM_TC_CNTR_LO);
2324 TPDM_LOCK(drvdata);
2325 }
2326 mutex_unlock(&drvdata->lock);
2327 return size;
2328}
2329static DEVICE_ATTR(tc_count_val_lo, S_IRUGO | S_IWUSR,
2330 tpdm_show_tc_count_val_lo, tpdm_store_tc_count_val_lo);
2331
2332static ssize_t tpdm_show_tc_count_val_hi(struct device *dev,
2333 struct device_attribute *attr,
2334 char *buf)
2335{
2336 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2337 unsigned long val;
2338
2339 if (!test_bit(TPDM_DS_TC, drvdata->enable_ds))
2340 return -EPERM;
2341
2342 mutex_lock(&drvdata->lock);
2343 if (!drvdata->enable) {
2344 mutex_unlock(&drvdata->lock);
2345 return -EPERM;
2346 }
2347
2348 TPDM_UNLOCK(drvdata);
2349 val = tpdm_readl(drvdata, TPDM_TC_CNTR_HI);
2350 TPDM_LOCK(drvdata);
2351 mutex_unlock(&drvdata->lock);
2352 return scnprintf(buf, PAGE_SIZE, "%lx\n", val);
2353}
2354
2355static ssize_t tpdm_store_tc_count_val_hi(struct device *dev,
2356 struct device_attribute *attr,
2357 const char *buf,
2358 size_t size)
2359{
2360 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2361 unsigned long val, select;
2362
2363 if (kstrtoul(buf, 16, &val))
2364 return -EINVAL;
2365 if (!test_bit(TPDM_DS_TC, drvdata->enable_ds))
2366 return -EPERM;
2367
2368 mutex_lock(&drvdata->lock);
2369 if (!drvdata->enable) {
2370 mutex_unlock(&drvdata->lock);
2371 return -EPERM;
2372 }
2373
2374 if (val) {
2375 TPDM_UNLOCK(drvdata);
2376 select = tpdm_readl(drvdata, TPDM_TC_SELR);
2377 select = (select >> 11) & 0x3;
2378
2379 /* Check if selected counter is disabled */
2380 if (BVAL(tpdm_readl(drvdata, TPDM_TC_CNTENSET), select)) {
2381 mutex_unlock(&drvdata->lock);
2382 return -EPERM;
2383 }
2384
2385 tpdm_writel(drvdata, val, TPDM_TC_CNTR_HI);
2386 TPDM_LOCK(drvdata);
2387 }
2388 mutex_unlock(&drvdata->lock);
2389 return size;
2390}
2391static DEVICE_ATTR(tc_count_val_hi, S_IRUGO | S_IWUSR,
2392 tpdm_show_tc_count_val_hi, tpdm_store_tc_count_val_hi);
2393
2394static ssize_t tpdm_show_tc_shadow_val_lo(struct device *dev,
2395 struct device_attribute *attr,
2396 char *buf)
2397{
2398 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2399 ssize_t size = 0;
2400 int i = 0;
2401
2402 if (!test_bit(TPDM_DS_TC, drvdata->enable_ds))
2403 return -EPERM;
2404
2405 mutex_lock(&drvdata->lock);
2406 if (!drvdata->enable) {
2407 mutex_unlock(&drvdata->lock);
2408 return -EPERM;
2409 }
2410
2411 TPDM_UNLOCK(drvdata);
2412 for (i = 0; i < TPDM_TC_MAX_COUNTERS; i++) {
2413 size += scnprintf(buf + size, PAGE_SIZE - size,
2414 "Index: 0x%x Value: 0x%x\n", i,
2415 tpdm_readl(drvdata, TPDM_TC_SHADOW_LO(i)));
2416 }
2417 TPDM_LOCK(drvdata);
2418 mutex_unlock(&drvdata->lock);
2419 return size;
2420}
2421static DEVICE_ATTR(tc_shadow_val_lo, S_IRUGO | S_IWUSR,
2422 tpdm_show_tc_shadow_val_lo, NULL);
2423
2424static ssize_t tpdm_show_tc_shadow_val_hi(struct device *dev,
2425 struct device_attribute *attr,
2426 char *buf)
2427{
2428 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2429 ssize_t size = 0;
2430 int i = 0;
2431
2432 if (!test_bit(TPDM_DS_TC, drvdata->enable_ds))
2433 return -EPERM;
2434
2435 mutex_lock(&drvdata->lock);
2436 if (!drvdata->enable) {
2437 mutex_unlock(&drvdata->lock);
2438 return -EPERM;
2439 }
2440
2441 TPDM_UNLOCK(drvdata);
2442 for (i = 0; i < TPDM_TC_MAX_COUNTERS; i++) {
2443 size += scnprintf(buf + size, PAGE_SIZE - size,
2444 "Index: 0x%x Value: 0x%x\n", i,
2445 tpdm_readl(drvdata, TPDM_TC_SHADOW_HI(i)));
2446 }
2447 TPDM_LOCK(drvdata);
2448 mutex_unlock(&drvdata->lock);
2449 return size;
2450}
2451static DEVICE_ATTR(tc_shadow_val_hi, S_IRUGO | S_IWUSR,
2452 tpdm_show_tc_shadow_val_hi, NULL);
2453
2454static ssize_t tpdm_show_tc_sw_inc(struct device *dev,
2455 struct device_attribute *attr,
2456 char *buf)
2457{
2458 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2459 unsigned long val;
2460
2461 if (!test_bit(TPDM_DS_TC, drvdata->enable_ds))
2462 return -EPERM;
2463
2464 mutex_lock(&drvdata->lock);
2465 if (!drvdata->enable) {
2466 mutex_unlock(&drvdata->lock);
2467 return -EPERM;
2468 }
2469
2470 TPDM_UNLOCK(drvdata);
2471 val = tpdm_readl(drvdata, TPDM_TC_SWINC);
2472 TPDM_LOCK(drvdata);
2473 mutex_unlock(&drvdata->lock);
2474 return scnprintf(buf, PAGE_SIZE, "%lx\n", val);
2475}
2476
2477static ssize_t tpdm_store_tc_sw_inc(struct device *dev,
2478 struct device_attribute *attr,
2479 const char *buf,
2480 size_t size)
2481{
2482 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2483 unsigned long val;
2484
2485 if (kstrtoul(buf, 16, &val))
2486 return -EINVAL;
2487 if (!test_bit(TPDM_DS_TC, drvdata->enable_ds))
2488 return -EPERM;
2489
2490 mutex_lock(&drvdata->lock);
2491 if (!drvdata->enable) {
2492 mutex_unlock(&drvdata->lock);
2493 return -EPERM;
2494 }
2495
2496 if (val) {
2497 TPDM_UNLOCK(drvdata);
2498 tpdm_writel(drvdata, val, TPDM_TC_SWINC);
2499 TPDM_LOCK(drvdata);
2500 }
2501 mutex_unlock(&drvdata->lock);
2502 return size;
2503}
2504static DEVICE_ATTR(tc_sw_inc, S_IRUGO | S_IWUSR,
2505 tpdm_show_tc_sw_inc, tpdm_store_tc_sw_inc);
2506
2507static ssize_t tpdm_store_tc_msr(struct device *dev,
2508 struct device_attribute *attr,
2509 const char *buf,
2510 size_t size)
2511{
2512 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2513 unsigned int num, val;
2514 int nval;
2515
2516 if (!drvdata->msr_support)
2517 return -EINVAL;
2518
2519 if (!test_bit(TPDM_DS_TC, drvdata->datasets))
2520 return -EPERM;
2521
2522 nval = sscanf(buf, "%u %x", &num, &val);
2523 if (nval != 2)
2524 return -EINVAL;
2525
2526 if (num >= TPDM_TC_MAX_MSR)
2527 return -EINVAL;
2528
2529 mutex_lock(&drvdata->lock);
2530 drvdata->tc->msr[num] = val;
2531 mutex_unlock(&drvdata->lock);
2532 return size;
2533}
2534static DEVICE_ATTR(tc_msr, S_IWUSR, NULL, tpdm_store_tc_msr);
2535
2536static ssize_t tpdm_show_dsb_mode(struct device *dev,
2537 struct device_attribute *attr,
2538 char *buf)
2539{
2540 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2541
2542 if (!test_bit(TPDM_DS_DSB, drvdata->datasets))
2543 return -EPERM;
2544
2545 return scnprintf(buf, PAGE_SIZE, "%lx\n",
2546 (unsigned long)drvdata->dsb->mode);
2547}
2548
2549static ssize_t tpdm_store_dsb_mode(struct device *dev,
2550 struct device_attribute *attr,
2551 const char *buf,
2552 size_t size)
2553{
2554 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2555 unsigned long val;
2556
2557 if (kstrtoul(buf, 16, &val))
2558 return -EINVAL;
2559 if (!test_bit(TPDM_DS_DSB, drvdata->datasets))
2560 return -EPERM;
2561
2562 mutex_lock(&drvdata->lock);
2563 drvdata->dsb->mode = val & TPDM_MODE_ALL;
2564 mutex_unlock(&drvdata->lock);
2565 return size;
2566}
2567static DEVICE_ATTR(dsb_mode, S_IRUGO | S_IWUSR,
2568 tpdm_show_dsb_mode, tpdm_store_dsb_mode);
2569
2570static ssize_t tpdm_show_dsb_edge_ctrl(struct device *dev,
2571 struct device_attribute *attr,
2572 char *buf)
2573{
2574 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2575 ssize_t size = 0;
2576 int i;
2577
2578 if (!test_bit(TPDM_DS_DSB, drvdata->datasets))
2579 return -EPERM;
2580
2581 mutex_lock(&drvdata->lock);
2582 for (i = 0; i < TPDM_DSB_MAX_EDCR; i++) {
2583 size += scnprintf(buf + size, PAGE_SIZE - size,
2584 "Index:0x%x Val:0x%x\n", i,
2585 drvdata->dsb->edge_ctrl[i]);
2586 }
2587 mutex_unlock(&drvdata->lock);
2588 return size;
2589}
2590
2591static ssize_t tpdm_store_dsb_edge_ctrl(struct device *dev,
2592 struct device_attribute *attr,
2593 const char *buf,
2594 size_t size)
2595{
2596 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2597 unsigned long start, end, edge_ctrl;
2598 uint32_t val;
2599 int i, bit, reg;
2600
2601 if (sscanf(buf, "%lx %lx %lx", &start, &end, &edge_ctrl) != 3)
2602 return -EINVAL;
2603 if (!test_bit(TPDM_DS_DSB, drvdata->datasets) ||
2604 (start >= TPDM_DSB_MAX_LINES) || (end >= TPDM_DSB_MAX_LINES) ||
2605 edge_ctrl > 0x2)
2606 return -EPERM;
2607
2608 mutex_lock(&drvdata->lock);
2609 for (i = start; i <= end; i++) {
2610 reg = i / (NUM_OF_BITS / 2);
2611 bit = i % (NUM_OF_BITS / 2);
2612 bit = bit * 2;
2613
2614 val = drvdata->dsb->edge_ctrl[reg];
2615 val = val | (edge_ctrl << bit);
2616 drvdata->dsb->edge_ctrl[reg] = val;
2617 }
2618 mutex_unlock(&drvdata->lock);
2619 return size;
2620}
2621static DEVICE_ATTR(dsb_edge_ctrl, S_IRUGO | S_IWUSR,
2622 tpdm_show_dsb_edge_ctrl, tpdm_store_dsb_edge_ctrl);
2623
2624static ssize_t tpdm_show_dsb_edge_ctrl_mask(struct device *dev,
2625 struct device_attribute *attr,
2626 char *buf)
2627{
2628 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2629 ssize_t size = 0;
2630 int i;
2631
2632 if (!test_bit(TPDM_DS_DSB, drvdata->datasets))
2633 return -EPERM;
2634
2635 mutex_lock(&drvdata->lock);
2636 for (i = 0; i < TPDM_DSB_MAX_EDCR / 2; i++) {
2637 size += scnprintf(buf + size, PAGE_SIZE - size,
2638 "Index:0x%x Val:0x%x\n", i,
2639 drvdata->dsb->edge_ctrl_mask[i]);
2640 }
2641 mutex_unlock(&drvdata->lock);
2642 return size;
2643}
2644
2645static ssize_t tpdm_store_dsb_edge_ctrl_mask(struct device *dev,
2646 struct device_attribute *attr,
2647 const char *buf,
2648 size_t size)
2649{
2650 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2651 unsigned long start, end, val;
2652 uint32_t set;
2653 int i, bit, reg;
2654
2655 if (sscanf(buf, "%lx %lx %lx", &start, &end, &val) != 3)
2656 return -EINVAL;
2657 if (!test_bit(TPDM_DS_DSB, drvdata->datasets) ||
2658 (start >= TPDM_DSB_MAX_LINES) || (end >= TPDM_DSB_MAX_LINES))
2659 return -EPERM;
2660
2661 mutex_lock(&drvdata->lock);
2662 for (i = start; i <= end; i++) {
2663 reg = i / NUM_OF_BITS;
2664 bit = (i % NUM_OF_BITS);
2665
2666 set = drvdata->dsb->edge_ctrl_mask[reg];
2667 if (val)
2668 set = set | BIT(bit);
2669 else
2670 set = set & ~BIT(bit);
2671 drvdata->dsb->edge_ctrl_mask[reg] = set;
2672 }
2673 mutex_unlock(&drvdata->lock);
2674 return size;
2675}
2676static DEVICE_ATTR(dsb_edge_ctrl_mask, S_IRUGO | S_IWUSR,
2677 tpdm_show_dsb_edge_ctrl_mask, tpdm_store_dsb_edge_ctrl_mask);
2678
2679static ssize_t tpdm_show_dsb_patt_val(struct device *dev,
2680 struct device_attribute *attr,
2681 char *buf)
2682{
2683 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2684 ssize_t size = 0;
2685 int i = 0;
2686
2687 if (!test_bit(TPDM_DS_DSB, drvdata->datasets))
2688 return -EPERM;
2689
2690 mutex_lock(&drvdata->lock);
2691 for (i = 0; i < TPDM_DSB_MAX_PATT; i++) {
2692 size += scnprintf(buf + size, PAGE_SIZE - size,
2693 "Index: 0x%x Value: 0x%x\n", i,
2694 drvdata->dsb->patt_val[i]);
2695 }
2696 mutex_unlock(&drvdata->lock);
2697 return size;
2698}
2699
2700static ssize_t tpdm_store_dsb_patt_val(struct device *dev,
2701 struct device_attribute *attr,
2702 const char *buf,
2703 size_t size)
2704{
2705 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2706 unsigned long index, val;
2707
2708 if (sscanf(buf, "%lx %lx", &index, &val) != 2)
2709 return -EINVAL;
2710 if (!test_bit(TPDM_DS_DSB, drvdata->datasets) ||
2711 index >= TPDM_DSB_MAX_PATT)
2712 return -EPERM;
2713
2714 mutex_lock(&drvdata->lock);
2715 drvdata->dsb->patt_val[index] = val;
2716 mutex_unlock(&drvdata->lock);
2717 return size;
2718}
2719static DEVICE_ATTR(dsb_patt_val, S_IRUGO | S_IWUSR,
2720 tpdm_show_dsb_patt_val, tpdm_store_dsb_patt_val);
2721
2722static ssize_t tpdm_show_dsb_patt_mask(struct device *dev,
2723 struct device_attribute *attr,
2724 char *buf)
2725{
2726 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2727 ssize_t size = 0;
2728 int i = 0;
2729
2730 if (!test_bit(TPDM_DS_DSB, drvdata->datasets))
2731 return -EPERM;
2732
2733 mutex_lock(&drvdata->lock);
2734 for (i = 0; i < TPDM_DSB_MAX_PATT; i++) {
2735 size += scnprintf(buf + size, PAGE_SIZE - size,
2736 "Index: 0x%x Value: 0x%x\n", i,
2737 drvdata->dsb->patt_mask[i]);
2738 }
2739 mutex_unlock(&drvdata->lock);
2740 return size;
2741}
2742
2743static ssize_t tpdm_store_dsb_patt_mask(struct device *dev,
2744 struct device_attribute *attr,
2745 const char *buf,
2746 size_t size)
2747{
2748 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2749 unsigned long index, val;
2750
2751 if (sscanf(buf, "%lx %lx", &index, &val) != 2)
2752 return -EINVAL;
2753 if (!test_bit(TPDM_DS_DSB, drvdata->datasets) ||
2754 index >= TPDM_DSB_MAX_PATT)
2755 return -EPERM;
2756
2757 mutex_lock(&drvdata->lock);
2758 drvdata->dsb->patt_mask[index] = val;
2759 mutex_unlock(&drvdata->lock);
2760 return size;
2761}
2762static DEVICE_ATTR(dsb_patt_mask, S_IRUGO | S_IWUSR,
2763 tpdm_show_dsb_patt_mask, tpdm_store_dsb_patt_mask);
2764
2765static ssize_t tpdm_show_dsb_patt_ts(struct device *dev,
2766 struct device_attribute *attr,
2767 char *buf)
2768{
2769 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2770
2771 if (!test_bit(TPDM_DS_DSB, drvdata->datasets))
2772 return -EPERM;
2773
2774 return scnprintf(buf, PAGE_SIZE, "%u\n",
2775 (unsigned int)drvdata->dsb->patt_ts);
2776}
2777
2778static ssize_t tpdm_store_dsb_patt_ts(struct device *dev,
2779 struct device_attribute *attr,
2780 const char *buf,
2781 size_t size)
2782{
2783 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2784 unsigned long val;
2785
2786 if (kstrtoul(buf, 16, &val))
2787 return -EINVAL;
2788 if (!test_bit(TPDM_DS_DSB, drvdata->datasets))
2789 return -EPERM;
2790
2791 mutex_lock(&drvdata->lock);
2792 if (val)
2793 drvdata->dsb->patt_ts = true;
2794 else
2795 drvdata->dsb->patt_ts = false;
2796 mutex_unlock(&drvdata->lock);
2797 return size;
2798}
2799static DEVICE_ATTR(dsb_patt_ts, S_IRUGO | S_IWUSR,
2800 tpdm_show_dsb_patt_ts, tpdm_store_dsb_patt_ts);
2801
2802static ssize_t tpdm_show_dsb_patt_type(struct device *dev,
2803 struct device_attribute *attr, char *buf)
2804{
2805 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2806
2807 if (!test_bit(TPDM_DS_DSB, drvdata->datasets))
2808 return -EPERM;
2809
2810 return scnprintf(buf, PAGE_SIZE, "%u\n",
2811 (unsigned int)drvdata->dsb->patt_type);
2812}
2813
2814static ssize_t tpdm_store_dsb_patt_type(struct device *dev,
2815 struct device_attribute *attr,
2816 const char *buf, size_t size)
2817{
2818 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2819 unsigned long val;
2820
2821 if (kstrtoul(buf, 16, &val))
2822 return -EINVAL;
2823 if (!test_bit(TPDM_DS_DSB, drvdata->datasets))
2824 return -EPERM;
2825
2826 mutex_lock(&drvdata->lock);
2827 if (val)
2828 drvdata->dsb->patt_type = true;
2829 else
2830 drvdata->dsb->patt_type = false;
2831 mutex_unlock(&drvdata->lock);
2832 return size;
2833}
2834static DEVICE_ATTR(dsb_patt_type, S_IRUGO | S_IWUSR,
2835 tpdm_show_dsb_patt_type, tpdm_store_dsb_patt_type);
2836
2837static ssize_t tpdm_show_dsb_trig_patt_val(struct device *dev,
2838 struct device_attribute *attr,
2839 char *buf)
2840{
2841 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2842 ssize_t size = 0;
2843 int i = 0;
2844
2845 if (!test_bit(TPDM_DS_DSB, drvdata->datasets))
2846 return -EPERM;
2847
2848 mutex_lock(&drvdata->lock);
2849 for (i = 0; i < TPDM_DSB_MAX_PATT; i++) {
2850 size += scnprintf(buf + size, PAGE_SIZE - size,
2851 "Index: 0x%x Value: 0x%x\n", i,
2852 drvdata->dsb->trig_patt_val[i]);
2853 }
2854 mutex_unlock(&drvdata->lock);
2855 return size;
2856}
2857
2858static ssize_t tpdm_store_dsb_trig_patt_val(struct device *dev,
2859 struct device_attribute *attr,
2860 const char *buf,
2861 size_t size)
2862{
2863 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2864 unsigned long index, val;
2865
2866 if (sscanf(buf, "%lx %lx", &index, &val) != 2)
2867 return -EINVAL;
2868 if (!test_bit(TPDM_DS_DSB, drvdata->datasets) ||
2869 index >= TPDM_DSB_MAX_PATT)
2870 return -EPERM;
2871
2872 mutex_lock(&drvdata->lock);
2873 drvdata->dsb->trig_patt_val[index] = val;
2874 mutex_unlock(&drvdata->lock);
2875 return size;
2876}
2877static DEVICE_ATTR(dsb_trig_patt_val, S_IRUGO | S_IWUSR,
2878 tpdm_show_dsb_trig_patt_val, tpdm_store_dsb_trig_patt_val);
2879
2880static ssize_t tpdm_show_dsb_trig_patt_mask(struct device *dev,
2881 struct device_attribute *attr,
2882 char *buf)
2883{
2884 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2885 ssize_t size = 0;
2886 int i = 0;
2887
2888 if (!test_bit(TPDM_DS_DSB, drvdata->datasets))
2889 return -EPERM;
2890
2891 mutex_lock(&drvdata->lock);
2892 for (i = 0; i < TPDM_DSB_MAX_PATT; i++) {
2893 size += scnprintf(buf + size, PAGE_SIZE - size,
2894 "Index: 0x%x Value: 0x%x\n", i,
2895 drvdata->dsb->trig_patt_mask[i]);
2896 }
2897 mutex_unlock(&drvdata->lock);
2898 return size;
2899}
2900
2901static ssize_t tpdm_store_dsb_trig_patt_mask(struct device *dev,
2902 struct device_attribute *attr,
2903 const char *buf,
2904 size_t size)
2905{
2906 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2907 unsigned long index, val;
2908
2909 if (sscanf(buf, "%lx %lx", &index, &val) != 2)
2910 return -EINVAL;
2911 if (!test_bit(TPDM_DS_DSB, drvdata->datasets) ||
2912 index >= TPDM_DSB_MAX_PATT)
2913 return -EPERM;
2914
2915 mutex_lock(&drvdata->lock);
2916 drvdata->dsb->trig_patt_mask[index] = val;
2917 mutex_unlock(&drvdata->lock);
2918 return size;
2919}
2920static DEVICE_ATTR(dsb_trig_patt_mask, S_IRUGO | S_IWUSR,
2921 tpdm_show_dsb_trig_patt_mask, tpdm_store_dsb_trig_patt_mask);
2922
2923static ssize_t tpdm_show_dsb_trig_ts(struct device *dev,
2924 struct device_attribute *attr,
2925 char *buf)
2926{
2927 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2928
2929 if (!test_bit(TPDM_DS_DSB, drvdata->datasets))
2930 return -EPERM;
2931
2932 return scnprintf(buf, PAGE_SIZE, "%u\n",
2933 (unsigned int)drvdata->dsb->trig_ts);
2934}
2935
2936static ssize_t tpdm_store_dsb_trig_ts(struct device *dev,
2937 struct device_attribute *attr,
2938 const char *buf,
2939 size_t size)
2940{
2941 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2942 unsigned long val;
2943
2944 if (kstrtoul(buf, 16, &val))
2945 return -EINVAL;
2946 if (!test_bit(TPDM_DS_DSB, drvdata->datasets))
2947 return -EPERM;
2948
2949 mutex_lock(&drvdata->lock);
2950 if (val)
2951 drvdata->dsb->trig_ts = true;
2952 else
2953 drvdata->dsb->trig_ts = false;
2954 mutex_unlock(&drvdata->lock);
2955 return size;
2956}
2957static DEVICE_ATTR(dsb_trig_ts, S_IRUGO | S_IWUSR,
2958 tpdm_show_dsb_trig_ts, tpdm_store_dsb_trig_ts);
2959
2960static ssize_t tpdm_show_dsb_select_val(struct device *dev,
2961 struct device_attribute *attr,
2962 char *buf)
2963{
2964 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2965 ssize_t size = 0;
2966 int i;
2967
2968 if (!test_bit(TPDM_DS_DSB, drvdata->datasets))
2969 return -EPERM;
2970
2971 mutex_lock(&drvdata->lock);
2972 for (i = 0; i < TPDM_DSB_MAX_SELECT; i++) {
2973 size += scnprintf(buf + size, PAGE_SIZE - size,
2974 "Index:0x%x Val:0x%x\n", i,
2975 drvdata->dsb->select_val[i]);
2976 }
2977 mutex_unlock(&drvdata->lock);
2978 return size;
2979}
2980
2981static ssize_t tpdm_store_dsb_select_val(struct device *dev,
2982 struct device_attribute *attr,
2983 const char *buf,
2984 size_t size)
2985{
2986 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
2987 unsigned long start, end;
2988 uint32_t val;
2989 int i, bit, reg;
2990
2991 if (sscanf(buf, "%lx %lx", &start, &end) != 2)
2992 return -EINVAL;
2993 if (!test_bit(TPDM_DS_DSB, drvdata->datasets) ||
2994 (start >= TPDM_DSB_MAX_LINES) || (end >= TPDM_DSB_MAX_LINES))
2995 return -EPERM;
2996
2997 mutex_lock(&drvdata->lock);
2998 for (i = start; i <= end; i++) {
2999 reg = i / NUM_OF_BITS;
3000 bit = (i % NUM_OF_BITS);
3001
3002 val = drvdata->dsb->select_val[reg];
3003 val = val | BIT(bit);
3004 drvdata->dsb->select_val[reg] = val;
3005 }
3006 mutex_unlock(&drvdata->lock);
3007 return size;
3008}
3009static DEVICE_ATTR(dsb_select_val, S_IRUGO | S_IWUSR,
3010 tpdm_show_dsb_select_val, tpdm_store_dsb_select_val);
3011
3012static ssize_t tpdm_store_dsb_msr(struct device *dev,
3013 struct device_attribute *attr,
3014 const char *buf,
3015 size_t size)
3016{
3017 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
3018 unsigned int num, val;
3019 int nval;
3020
3021 if (!drvdata->msr_support)
3022 return -EINVAL;
3023
3024 if (!test_bit(TPDM_DS_DSB, drvdata->datasets))
3025 return -EPERM;
3026
3027 nval = sscanf(buf, "%u %x", &num, &val);
3028 if (nval != 2)
3029 return -EINVAL;
3030
3031 if (num >= TPDM_DSB_MAX_MSR)
3032 return -EINVAL;
3033
3034 mutex_lock(&drvdata->lock);
3035 drvdata->dsb->msr[num] = val;
3036 mutex_unlock(&drvdata->lock);
3037 return size;
3038}
3039static DEVICE_ATTR(dsb_msr, S_IWUSR, NULL, tpdm_store_dsb_msr);
3040
3041static ssize_t tpdm_show_cmb_available_modes(struct device *dev,
3042 struct device_attribute *attr,
3043 char *buf)
3044{
3045 return scnprintf(buf, PAGE_SIZE, "%s\n", "continuous trace_on_change");
3046}
3047static DEVICE_ATTR(cmb_available_modes, S_IRUGO, tpdm_show_cmb_available_modes,
3048 NULL);
3049
3050static ssize_t tpdm_show_cmb_mode(struct device *dev,
3051 struct device_attribute *attr,
3052 char *buf)
3053{
3054 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
3055
3056 if (!test_bit(TPDM_DS_CMB, drvdata->datasets))
3057 return -EPERM;
3058
3059 return scnprintf(buf, PAGE_SIZE, "%s\n",
3060 drvdata->cmb->mode == TPDM_CMB_MODE_CONTINUOUS ?
3061 "continuous" : "trace_on_change");
3062}
3063
3064static ssize_t tpdm_store_cmb_mode(struct device *dev,
3065 struct device_attribute *attr,
3066 const char *buf,
3067 size_t size)
3068{
3069 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
3070 char str[20] = "";
3071
3072 if (strlen(buf) >= 20)
3073 return -EINVAL;
3074 if (sscanf(buf, "%s", str) != 1)
3075 return -EINVAL;
3076 if (!test_bit(TPDM_DS_CMB, drvdata->datasets))
3077 return -EPERM;
3078
3079 mutex_lock(&drvdata->lock);
3080 if (!strcmp(str, "continuous")) {
3081 drvdata->cmb->mode = TPDM_CMB_MODE_CONTINUOUS;
3082 } else if (!strcmp(str, "trace_on_change")) {
3083 drvdata->cmb->mode = TPDM_CMB_MODE_TRACE_ON_CHANGE;
3084 } else {
3085 mutex_unlock(&drvdata->lock);
3086 return -EINVAL;
3087 }
3088 mutex_unlock(&drvdata->lock);
3089 return size;
3090}
3091static DEVICE_ATTR(cmb_mode, S_IRUGO | S_IWUSR,
3092 tpdm_show_cmb_mode, tpdm_store_cmb_mode);
3093
3094static ssize_t tpdm_show_cmb_patt_val_lsb(struct device *dev,
3095 struct device_attribute *attr,
3096 char *buf)
3097{
3098 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
3099 unsigned long val;
3100
3101 if (!test_bit(TPDM_DS_CMB, drvdata->datasets))
3102 return -EPERM;
3103
3104 val = drvdata->cmb->patt_val[TPDM_CMB_LSB];
3105
3106 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
3107}
3108
3109static ssize_t tpdm_store_cmb_patt_val_lsb(struct device *dev,
3110 struct device_attribute *attr,
3111 const char *buf, size_t size)
3112{
3113 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
3114 unsigned long val;
3115
3116 if (kstrtoul(buf, 16, &val))
3117 return -EINVAL;
3118 if (!test_bit(TPDM_DS_CMB, drvdata->datasets))
3119 return -EPERM;
3120
3121 mutex_lock(&drvdata->lock);
3122 drvdata->cmb->patt_val[TPDM_CMB_LSB] = val;
3123 mutex_unlock(&drvdata->lock);
3124 return size;
3125}
3126static DEVICE_ATTR(cmb_patt_val_lsb, S_IRUGO | S_IWUSR,
3127 tpdm_show_cmb_patt_val_lsb,
3128 tpdm_store_cmb_patt_val_lsb);
3129
3130static ssize_t tpdm_show_cmb_patt_mask_lsb(struct device *dev,
3131 struct device_attribute *attr,
3132 char *buf)
3133{
3134 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
3135 unsigned long val;
3136
3137 if (!test_bit(TPDM_DS_CMB, drvdata->datasets))
3138 return -EPERM;
3139
3140 val = drvdata->cmb->patt_mask[TPDM_CMB_LSB];
3141
3142 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
3143}
3144
3145static ssize_t tpdm_store_cmb_patt_mask_lsb(struct device *dev,
3146 struct device_attribute *attr,
3147 const char *buf, size_t size)
3148{
3149 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
3150 unsigned long val;
3151
3152 if (kstrtoul(buf, 16, &val))
3153 return -EINVAL;
3154 if (!test_bit(TPDM_DS_CMB, drvdata->datasets))
3155 return -EPERM;
3156
3157 mutex_lock(&drvdata->lock);
3158 drvdata->cmb->patt_mask[TPDM_CMB_LSB] = val;
3159 mutex_unlock(&drvdata->lock);
3160 return size;
3161}
3162static DEVICE_ATTR(cmb_patt_mask_lsb, S_IRUGO | S_IWUSR,
3163 tpdm_show_cmb_patt_mask_lsb, tpdm_store_cmb_patt_mask_lsb);
3164
3165static ssize_t tpdm_show_cmb_patt_val_msb(struct device *dev,
3166 struct device_attribute *attr,
3167 char *buf)
3168{
3169 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
3170 unsigned long val;
3171
3172 if (!test_bit(TPDM_DS_CMB, drvdata->datasets))
3173 return -EPERM;
3174
3175 val = drvdata->cmb->patt_val[TPDM_CMB_MSB];
3176
3177 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
3178}
3179
3180static ssize_t tpdm_store_cmb_patt_val_msb(struct device *dev,
3181 struct device_attribute *attr,
3182 const char *buf, size_t size)
3183{
3184 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
3185 unsigned long val;
3186
3187 if (kstrtoul(buf, 16, &val))
3188 return -EINVAL;
3189 if (!test_bit(TPDM_DS_CMB, drvdata->datasets))
3190 return -EPERM;
3191
3192 mutex_lock(&drvdata->lock);
3193 drvdata->cmb->patt_val[TPDM_CMB_MSB] = val;
3194 mutex_unlock(&drvdata->lock);
3195 return size;
3196}
3197static DEVICE_ATTR(cmb_patt_val_msb, S_IRUGO | S_IWUSR,
3198 tpdm_show_cmb_patt_val_msb,
3199 tpdm_store_cmb_patt_val_msb);
3200
3201static ssize_t tpdm_show_cmb_patt_mask_msb(struct device *dev,
3202 struct device_attribute *attr,
3203 char *buf)
3204{
3205 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
3206 unsigned long val;
3207
3208 if (!test_bit(TPDM_DS_CMB, drvdata->datasets))
3209 return -EPERM;
3210
3211 val = drvdata->cmb->patt_mask[TPDM_CMB_MSB];
3212
3213 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
3214}
3215
3216static ssize_t tpdm_store_cmb_patt_mask_msb(struct device *dev,
3217 struct device_attribute *attr,
3218 const char *buf, size_t size)
3219{
3220 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
3221 unsigned long val;
3222
3223 if (kstrtoul(buf, 16, &val))
3224 return -EINVAL;
3225 if (!test_bit(TPDM_DS_CMB, drvdata->datasets))
3226 return -EPERM;
3227
3228 mutex_lock(&drvdata->lock);
3229 drvdata->cmb->patt_mask[TPDM_CMB_MSB] = val;
3230 mutex_unlock(&drvdata->lock);
3231 return size;
3232}
3233static DEVICE_ATTR(cmb_patt_mask_msb, S_IRUGO | S_IWUSR,
3234 tpdm_show_cmb_patt_mask_msb, tpdm_store_cmb_patt_mask_msb);
3235
3236static ssize_t tpdm_show_cmb_patt_ts(struct device *dev,
3237 struct device_attribute *attr,
3238 char *buf)
3239{
3240 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
3241
3242 if (!test_bit(TPDM_DS_CMB, drvdata->datasets))
3243 return -EPERM;
3244
3245 return scnprintf(buf, PAGE_SIZE, "%u\n",
3246 (unsigned int)drvdata->cmb->patt_ts);
3247}
3248
3249static ssize_t tpdm_store_cmb_patt_ts(struct device *dev,
3250 struct device_attribute *attr,
3251 const char *buf,
3252 size_t size)
3253{
3254 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
3255 unsigned long val;
3256
3257 if (kstrtoul(buf, 16, &val))
3258 return -EINVAL;
3259 if (!test_bit(TPDM_DS_CMB, drvdata->datasets))
3260 return -EPERM;
3261
3262 mutex_lock(&drvdata->lock);
3263 if (val)
3264 drvdata->cmb->patt_ts = true;
3265 else
3266 drvdata->cmb->patt_ts = false;
3267 mutex_unlock(&drvdata->lock);
3268 return size;
3269}
3270static DEVICE_ATTR(cmb_patt_ts, S_IRUGO | S_IWUSR,
3271 tpdm_show_cmb_patt_ts, tpdm_store_cmb_patt_ts);
3272
3273static ssize_t tpdm_show_cmb_trig_patt_val_lsb(struct device *dev,
3274 struct device_attribute *attr,
3275 char *buf)
3276{
3277 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
3278 unsigned long val;
3279
3280 if (!test_bit(TPDM_DS_CMB, drvdata->datasets))
3281 return -EPERM;
3282
3283 val = drvdata->cmb->trig_patt_val[TPDM_CMB_LSB];
3284
3285 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
3286}
3287
3288static ssize_t tpdm_store_cmb_trig_patt_val_lsb(struct device *dev,
3289 struct device_attribute *attr,
3290 const char *buf, size_t size)
3291{
3292 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
3293 unsigned long val;
3294
3295 if (kstrtoul(buf, 16, &val))
3296 return -EINVAL;
3297 if (!test_bit(TPDM_DS_CMB, drvdata->datasets))
3298 return -EPERM;
3299
3300 mutex_lock(&drvdata->lock);
3301 drvdata->cmb->trig_patt_val[TPDM_CMB_LSB] = val;
3302 mutex_unlock(&drvdata->lock);
3303 return size;
3304}
3305static DEVICE_ATTR(cmb_trig_patt_val_lsb, S_IRUGO | S_IWUSR,
3306 tpdm_show_cmb_trig_patt_val_lsb,
3307 tpdm_store_cmb_trig_patt_val_lsb);
3308
3309static ssize_t tpdm_show_cmb_trig_patt_mask_lsb(struct device *dev,
3310 struct device_attribute *attr,
3311 char *buf)
3312{
3313 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
3314 unsigned long val;
3315
3316 if (!test_bit(TPDM_DS_CMB, drvdata->datasets))
3317 return -EPERM;
3318
3319 val = drvdata->cmb->trig_patt_mask[TPDM_CMB_LSB];
3320
3321 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
3322}
3323
3324static ssize_t tpdm_store_cmb_trig_patt_mask_lsb(struct device *dev,
3325 struct device_attribute *attr,
3326 const char *buf, size_t size)
3327{
3328 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
3329 unsigned long val;
3330
3331 if (kstrtoul(buf, 16, &val))
3332 return -EINVAL;
3333 if (!test_bit(TPDM_DS_CMB, drvdata->datasets))
3334 return -EPERM;
3335
3336 mutex_lock(&drvdata->lock);
3337 drvdata->cmb->trig_patt_mask[TPDM_CMB_LSB] = val;
3338 mutex_unlock(&drvdata->lock);
3339 return size;
3340}
3341static DEVICE_ATTR(cmb_trig_patt_mask_lsb, S_IRUGO | S_IWUSR,
3342 tpdm_show_cmb_trig_patt_mask_lsb,
3343 tpdm_store_cmb_trig_patt_mask_lsb);
3344
3345static ssize_t tpdm_show_cmb_trig_patt_val_msb(struct device *dev,
3346 struct device_attribute *attr,
3347 char *buf)
3348{
3349 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
3350 unsigned long val;
3351
3352 if (!test_bit(TPDM_DS_CMB, drvdata->datasets))
3353 return -EPERM;
3354
3355 val = drvdata->cmb->trig_patt_val[TPDM_CMB_MSB];
3356
3357 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
3358}
3359
3360static ssize_t tpdm_store_cmb_trig_patt_val_msb(struct device *dev,
3361 struct device_attribute *attr,
3362 const char *buf, size_t size)
3363{
3364 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
3365 unsigned long val;
3366
3367 if (kstrtoul(buf, 16, &val))
3368 return -EINVAL;
3369 if (!test_bit(TPDM_DS_CMB, drvdata->datasets))
3370 return -EPERM;
3371
3372 mutex_lock(&drvdata->lock);
3373 drvdata->cmb->trig_patt_val[TPDM_CMB_MSB] = val;
3374 mutex_unlock(&drvdata->lock);
3375 return size;
3376}
3377static DEVICE_ATTR(cmb_trig_patt_val_msb, S_IRUGO | S_IWUSR,
3378 tpdm_show_cmb_trig_patt_val_msb,
3379 tpdm_store_cmb_trig_patt_val_msb);
3380
3381static ssize_t tpdm_show_cmb_trig_patt_mask_msb(struct device *dev,
3382 struct device_attribute *attr,
3383 char *buf)
3384{
3385 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
3386 unsigned long val;
3387
3388 if (!test_bit(TPDM_DS_CMB, drvdata->datasets))
3389 return -EPERM;
3390
3391 val = drvdata->cmb->trig_patt_mask[TPDM_CMB_MSB];
3392
3393 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
3394}
3395
3396static ssize_t tpdm_store_cmb_trig_patt_mask_msb(struct device *dev,
3397 struct device_attribute *attr,
3398 const char *buf, size_t size)
3399{
3400 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
3401 unsigned long val;
3402
3403 if (kstrtoul(buf, 16, &val))
3404 return -EINVAL;
3405 if (!test_bit(TPDM_DS_CMB, drvdata->datasets))
3406 return -EPERM;
3407
3408 mutex_lock(&drvdata->lock);
3409 drvdata->cmb->trig_patt_mask[TPDM_CMB_MSB] = val;
3410 mutex_unlock(&drvdata->lock);
3411 return size;
3412}
3413static DEVICE_ATTR(cmb_trig_patt_mask_msb, S_IRUGO | S_IWUSR,
3414 tpdm_show_cmb_trig_patt_mask_msb,
3415 tpdm_store_cmb_trig_patt_mask_msb);
3416
3417static ssize_t tpdm_show_cmb_trig_ts(struct device *dev,
3418 struct device_attribute *attr,
3419 char *buf)
3420{
3421 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
3422
3423 if (!test_bit(TPDM_DS_CMB, drvdata->datasets))
3424 return -EPERM;
3425
3426 return scnprintf(buf, PAGE_SIZE, "%u\n",
3427 (unsigned int)drvdata->cmb->trig_ts);
3428}
3429
3430static ssize_t tpdm_store_cmb_trig_ts(struct device *dev,
3431 struct device_attribute *attr,
3432 const char *buf,
3433 size_t size)
3434{
3435 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
3436 unsigned long val;
3437
3438 if (kstrtoul(buf, 16, &val))
3439 return -EINVAL;
3440 if (!test_bit(TPDM_DS_CMB, drvdata->datasets))
3441 return -EPERM;
3442
3443 mutex_lock(&drvdata->lock);
3444 if (val)
3445 drvdata->cmb->trig_ts = true;
3446 else
3447 drvdata->cmb->trig_ts = false;
3448 mutex_unlock(&drvdata->lock);
3449 return size;
3450}
3451static DEVICE_ATTR(cmb_trig_ts, S_IRUGO | S_IWUSR,
3452 tpdm_show_cmb_trig_ts, tpdm_store_cmb_trig_ts);
3453
3454static ssize_t tpdm_store_cmb_msr(struct device *dev,
3455 struct device_attribute *attr,
3456 const char *buf,
3457 size_t size)
3458{
3459 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
3460 unsigned int num, val;
3461 int nval;
3462
3463 if (!drvdata->msr_support)
3464 return -EINVAL;
3465
3466 if (!test_bit(TPDM_DS_CMB, drvdata->datasets))
3467 return -EPERM;
3468
3469 nval = sscanf(buf, "%u %x", &num, &val);
3470 if (nval != 2)
3471 return -EINVAL;
3472
3473 if (num >= TPDM_CMB_MAX_MSR)
3474 return -EINVAL;
3475
3476 mutex_lock(&drvdata->lock);
3477 drvdata->cmb->msr[num] = val;
3478 mutex_unlock(&drvdata->lock);
3479 return size;
3480}
3481static DEVICE_ATTR(cmb_msr, S_IWUSR, NULL, tpdm_store_cmb_msr);
3482
3483static struct attribute *tpdm_bc_attrs[] = {
3484 &dev_attr_bc_capture_mode.attr,
3485 &dev_attr_bc_retrieval_mode.attr,
3486 &dev_attr_bc_reset_counters.attr,
3487 &dev_attr_bc_sat_mode.attr,
3488 &dev_attr_bc_enable_counters.attr,
3489 &dev_attr_bc_clear_counters.attr,
3490 &dev_attr_bc_enable_irq.attr,
3491 &dev_attr_bc_clear_irq.attr,
3492 &dev_attr_bc_trig_val_lo.attr,
3493 &dev_attr_bc_trig_val_hi.attr,
3494 &dev_attr_bc_enable_ganging.attr,
3495 &dev_attr_bc_overflow_val.attr,
3496 &dev_attr_bc_ovsr.attr,
3497 &dev_attr_bc_counter_sel.attr,
3498 &dev_attr_bc_count_val_lo.attr,
3499 &dev_attr_bc_count_val_hi.attr,
3500 &dev_attr_bc_shadow_val_lo.attr,
3501 &dev_attr_bc_shadow_val_hi.attr,
3502 &dev_attr_bc_sw_inc.attr,
3503 &dev_attr_bc_msr.attr,
3504 NULL,
3505};
3506
3507static struct attribute *tpdm_tc_attrs[] = {
3508 &dev_attr_tc_capture_mode.attr,
3509 &dev_attr_tc_retrieval_mode.attr,
3510 &dev_attr_tc_reset_counters.attr,
3511 &dev_attr_tc_sat_mode.attr,
3512 &dev_attr_tc_enable_counters.attr,
3513 &dev_attr_tc_clear_counters.attr,
3514 &dev_attr_tc_enable_irq.attr,
3515 &dev_attr_tc_clear_irq.attr,
3516 &dev_attr_tc_trig_sel.attr,
3517 &dev_attr_tc_trig_val_lo.attr,
3518 &dev_attr_tc_trig_val_hi.attr,
3519 &dev_attr_tc_ovsr_gp.attr,
3520 &dev_attr_tc_ovsr_impl.attr,
3521 &dev_attr_tc_counter_sel.attr,
3522 &dev_attr_tc_count_val_lo.attr,
3523 &dev_attr_tc_count_val_hi.attr,
3524 &dev_attr_tc_shadow_val_lo.attr,
3525 &dev_attr_tc_shadow_val_hi.attr,
3526 &dev_attr_tc_sw_inc.attr,
3527 &dev_attr_tc_msr.attr,
3528 NULL,
3529};
3530
3531static struct attribute *tpdm_dsb_attrs[] = {
3532 &dev_attr_dsb_mode.attr,
3533 &dev_attr_dsb_edge_ctrl.attr,
3534 &dev_attr_dsb_edge_ctrl_mask.attr,
3535 &dev_attr_dsb_patt_val.attr,
3536 &dev_attr_dsb_patt_mask.attr,
3537 &dev_attr_dsb_patt_ts.attr,
3538 &dev_attr_dsb_patt_type.attr,
3539 &dev_attr_dsb_trig_patt_val.attr,
3540 &dev_attr_dsb_trig_patt_mask.attr,
3541 &dev_attr_dsb_trig_ts.attr,
3542 &dev_attr_dsb_select_val.attr,
3543 &dev_attr_dsb_msr.attr,
3544 NULL,
3545};
3546
3547static struct attribute *tpdm_cmb_attrs[] = {
3548 &dev_attr_cmb_available_modes.attr,
3549 &dev_attr_cmb_mode.attr,
3550 &dev_attr_cmb_patt_val_lsb.attr,
3551 &dev_attr_cmb_patt_mask_lsb.attr,
3552 &dev_attr_cmb_patt_val_msb.attr,
3553 &dev_attr_cmb_patt_mask_msb.attr,
3554 &dev_attr_cmb_patt_ts.attr,
3555 &dev_attr_cmb_trig_patt_val_lsb.attr,
3556 &dev_attr_cmb_trig_patt_mask_lsb.attr,
3557 &dev_attr_cmb_trig_patt_val_msb.attr,
3558 &dev_attr_cmb_trig_patt_mask_msb.attr,
3559 &dev_attr_cmb_trig_ts.attr,
3560 &dev_attr_cmb_msr.attr,
3561 NULL,
3562};
3563
3564static struct attribute_group tpdm_bc_attr_grp = {
3565 .attrs = tpdm_bc_attrs,
3566};
3567
3568static struct attribute_group tpdm_tc_attr_grp = {
3569 .attrs = tpdm_tc_attrs,
3570};
3571
3572static struct attribute_group tpdm_dsb_attr_grp = {
3573 .attrs = tpdm_dsb_attrs,
3574};
3575
3576static struct attribute_group tpdm_cmb_attr_grp = {
3577 .attrs = tpdm_cmb_attrs,
3578};
3579
3580static struct attribute *tpdm_attrs[] = {
3581 &dev_attr_available_datasets.attr,
3582 &dev_attr_enable_datasets.attr,
3583 &dev_attr_gp_regs.attr,
3584 NULL,
3585};
3586
3587static struct attribute_group tpdm_attr_grp = {
3588 .attrs = tpdm_attrs,
3589};
3590static const struct attribute_group *tpdm_attr_grps[] = {
3591 &tpdm_attr_grp,
3592 &tpdm_bc_attr_grp,
3593 &tpdm_tc_attr_grp,
3594 &tpdm_dsb_attr_grp,
3595 &tpdm_cmb_attr_grp,
3596 NULL,
3597};
3598
3599static int tpdm_datasets_alloc(struct tpdm_drvdata *drvdata)
3600{
3601 if (test_bit(TPDM_DS_GPR, drvdata->datasets)) {
3602 drvdata->gpr = devm_kzalloc(drvdata->dev, sizeof(*drvdata->gpr),
3603 GFP_KERNEL);
3604 if (!drvdata->gpr)
3605 return -ENOMEM;
3606 }
3607 if (test_bit(TPDM_DS_BC, drvdata->datasets)) {
3608 drvdata->bc = devm_kzalloc(drvdata->dev, sizeof(*drvdata->bc),
3609 GFP_KERNEL);
3610 if (!drvdata->bc)
3611 return -ENOMEM;
3612 }
3613 if (test_bit(TPDM_DS_TC, drvdata->datasets)) {
3614 drvdata->tc = devm_kzalloc(drvdata->dev, sizeof(*drvdata->tc),
3615 GFP_KERNEL);
3616 if (!drvdata->tc)
3617 return -ENOMEM;
3618 }
3619 if (test_bit(TPDM_DS_DSB, drvdata->datasets)) {
3620 drvdata->dsb = devm_kzalloc(drvdata->dev, sizeof(*drvdata->dsb),
3621 GFP_KERNEL);
3622 if (!drvdata->dsb)
3623 return -ENOMEM;
3624 }
3625 if (test_bit(TPDM_DS_CMB, drvdata->datasets)) {
3626 drvdata->cmb = devm_kzalloc(drvdata->dev, sizeof(*drvdata->cmb),
3627 GFP_KERNEL);
3628 if (!drvdata->cmb)
3629 return -ENOMEM;
3630 }
3631 return 0;
3632}
3633
3634static void tpdm_init_default_data(struct tpdm_drvdata *drvdata)
3635{
3636 if (test_bit(TPDM_DS_BC, drvdata->datasets))
3637 drvdata->bc->retrieval_mode = TPDM_MODE_ATB;
3638
3639 if (test_bit(TPDM_DS_TC, drvdata->datasets))
3640 drvdata->tc->retrieval_mode = TPDM_MODE_ATB;
3641
3642 if (test_bit(TPDM_DS_DSB, drvdata->datasets))
3643 drvdata->dsb->trig_ts = true;
3644
3645 if (test_bit(TPDM_DS_CMB, drvdata->datasets))
3646 drvdata->cmb->trig_ts = true;
3647}
3648
3649static int tpdm_probe(struct platform_device *pdev)
3650{
3651 int ret, i;
3652 uint32_t pidr, devid;
3653 struct device *dev = &pdev->dev;
3654 struct coresight_platform_data *pdata;
3655 struct tpdm_drvdata *drvdata;
3656 struct resource *res;
3657 struct coresight_desc *desc;
3658 static int traceid = TPDM_TRACE_ID_START;
3659 uint32_t version;
3660
3661 pdata = of_get_coresight_platform_data(dev, pdev->dev.of_node);
3662 if (IS_ERR(pdata))
3663 return PTR_ERR(pdata);
3664 pdev->dev.platform_data = pdata;
3665
3666 drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
3667 if (!drvdata)
3668 return -ENOMEM;
3669 drvdata->dev = &pdev->dev;
3670 platform_set_drvdata(pdev, drvdata);
3671
3672 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tpdm-base");
3673 if (!res)
3674 return -ENODEV;
3675
3676 drvdata->base = devm_ioremap(dev, res->start, resource_size(res));
3677 if (!drvdata->base)
3678 return -ENOMEM;
3679
3680 drvdata->clk_enable = of_property_read_bool(pdev->dev.of_node,
3681 "qcom,clk-enable");
3682
3683 drvdata->msr_fix_req = of_property_read_bool(pdev->dev.of_node,
3684 "qcom,msr-fix-req");
3685
3686 mutex_init(&drvdata->lock);
3687
3688 drvdata->clk = devm_clk_get(dev, "core_clk");
3689 if (IS_ERR(drvdata->clk))
3690 return PTR_ERR(drvdata->clk);
3691
3692 ret = clk_set_rate(drvdata->clk, CORESIGHT_CLK_RATE_TRACE);
3693 if (ret)
3694 return ret;
3695
3696 ret = clk_prepare_enable(drvdata->clk);
3697 if (ret)
3698 return ret;
3699
3700 version = tpdm_readl(drvdata, CORESIGHT_PERIPHIDR2);
3701 drvdata->version = BMVAL(version, 4, 7);
3702
3703 if (drvdata->version)
3704 drvdata->msr_support = true;
3705
3706 pidr = tpdm_readl(drvdata, CORESIGHT_PERIPHIDR0);
3707 for (i = 0; i < TPDM_DATASETS; i++) {
3708 if (pidr & BIT(i)) {
3709 __set_bit(i, drvdata->datasets);
3710 __set_bit(i, drvdata->enable_ds);
3711 }
3712 }
3713
3714 ret = tpdm_datasets_alloc(drvdata);
3715 if (ret)
3716 return ret;
3717
3718 tpdm_init_default_data(drvdata);
3719
3720 devid = tpdm_readl(drvdata, CORESIGHT_DEVID);
3721 drvdata->tc_trig_type = BMVAL(devid, 27, 28);
3722 drvdata->bc_trig_type = BMVAL(devid, 25, 26);
3723 drvdata->bc_gang_type = BMVAL(devid, 23, 24);
3724 drvdata->bc_counters_avail = BMVAL(devid, 6, 10) + 1;
3725 drvdata->tc_counters_avail = BMVAL(devid, 4, 5) + 1;
3726
3727 clk_disable_unprepare(drvdata->clk);
3728
3729 drvdata->traceid = traceid++;
3730
3731 desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
3732 if (!desc)
3733 return -ENOMEM;
3734 desc->type = CORESIGHT_DEV_TYPE_SOURCE;
3735 desc->subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_PROC;
3736 desc->ops = &tpdm_cs_ops;
3737 desc->pdata = pdev->dev.platform_data;
3738 desc->dev = &pdev->dev;
3739 desc->groups = tpdm_attr_grps;
3740 drvdata->csdev = coresight_register(desc);
3741 if (IS_ERR(drvdata->csdev))
3742 return PTR_ERR(drvdata->csdev);
3743
3744 dev_dbg(drvdata->dev, "TPDM initialized\n");
3745
3746 if (boot_enable)
3747 coresight_enable(drvdata->csdev);
3748
3749 return 0;
3750}
3751
3752static int tpdm_remove(struct platform_device *pdev)
3753{
3754 struct tpdm_drvdata *drvdata = platform_get_drvdata(pdev);
3755
3756 coresight_unregister(drvdata->csdev);
3757 return 0;
3758}
3759
3760static const struct of_device_id tpdm_match[] = {
3761 {.compatible = "qcom,coresight-tpdm"},
3762 {}
3763};
3764
3765static struct platform_driver tpdm_driver = {
3766 .probe = tpdm_probe,
3767 .remove = tpdm_remove,
3768 .driver = {
3769 .name = "coresight-tpdm",
3770 .owner = THIS_MODULE,
3771 .of_match_table = tpdm_match,
3772 },
3773};
3774
3775static int __init tpdm_init(void)
3776{
3777 return platform_driver_register(&tpdm_driver);
3778}
3779module_init(tpdm_init);
3780
3781static void __exit tpdm_exit(void)
3782{
3783 platform_driver_unregister(&tpdm_driver);
3784}
3785module_exit(tpdm_exit);
3786
3787MODULE_LICENSE("GPL v2");
3788MODULE_DESCRIPTION("Trace, Profiling & Diagnostic Monitor driver");