1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2023-2025 Qualcomm Innovation Center, Inc. All rights reserved. 4 */ 5 6 #include <linux/amba/bus.h> 7 #include <linux/bitfield.h> 8 #include <linux/bitmap.h> 9 #include <linux/coresight.h> 10 #include <linux/coresight-pmu.h> 11 #include <linux/device.h> 12 #include <linux/err.h> 13 #include <linux/fs.h> 14 #include <linux/io.h> 15 #include <linux/kernel.h> 16 #include <linux/module.h> 17 #include <linux/of.h> 18 19 #include "coresight-priv.h" 20 #include "coresight-tpdm.h" 21 22 DEFINE_CORESIGHT_DEVLIST(tpdm_devs, "tpdm"); 23 24 static bool tpdm_has_dsb_dataset(struct tpdm_drvdata *drvdata) 25 { 26 return (drvdata->datasets & TPDM_PIDR0_DS_DSB); 27 } 28 29 static bool tpdm_has_cmb_dataset(struct tpdm_drvdata *drvdata) 30 { 31 return (drvdata->datasets & TPDM_PIDR0_DS_CMB); 32 } 33 34 static bool tpdm_has_mcmb_dataset(struct tpdm_drvdata *drvdata) 35 { 36 return (drvdata->datasets & TPDM_PIDR0_DS_MCMB); 37 } 38 39 /* Read dataset array member with the index number */ 40 static ssize_t tpdm_simple_dataset_show(struct device *dev, 41 struct device_attribute *attr, 42 char *buf) 43 { 44 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 45 struct tpdm_dataset_attribute *tpdm_attr = 46 container_of(attr, struct tpdm_dataset_attribute, attr); 47 48 switch (tpdm_attr->mem) { 49 case DSB_EDGE_CTRL: 50 if (tpdm_attr->idx >= TPDM_DSB_MAX_EDCR) 51 return -EINVAL; 52 return sysfs_emit(buf, "0x%x\n", 53 drvdata->dsb->edge_ctrl[tpdm_attr->idx]); 54 case DSB_EDGE_CTRL_MASK: 55 if (tpdm_attr->idx >= TPDM_DSB_MAX_EDCMR) 56 return -EINVAL; 57 return sysfs_emit(buf, "0x%x\n", 58 drvdata->dsb->edge_ctrl_mask[tpdm_attr->idx]); 59 case DSB_TRIG_PATT: 60 if (tpdm_attr->idx >= TPDM_DSB_MAX_PATT) 61 return -EINVAL; 62 return sysfs_emit(buf, "0x%x\n", 63 drvdata->dsb->trig_patt[tpdm_attr->idx]); 64 case DSB_TRIG_PATT_MASK: 65 if (tpdm_attr->idx >= TPDM_DSB_MAX_PATT) 66 return -EINVAL; 67 return sysfs_emit(buf, "0x%x\n", 68 drvdata->dsb->trig_patt_mask[tpdm_attr->idx]); 69 case DSB_PATT: 70 if (tpdm_attr->idx >= TPDM_DSB_MAX_PATT) 71 return -EINVAL; 72 return sysfs_emit(buf, "0x%x\n", 73 drvdata->dsb->patt_val[tpdm_attr->idx]); 74 case DSB_PATT_MASK: 75 if (tpdm_attr->idx >= TPDM_DSB_MAX_PATT) 76 return -EINVAL; 77 return sysfs_emit(buf, "0x%x\n", 78 drvdata->dsb->patt_mask[tpdm_attr->idx]); 79 case DSB_MSR: 80 if (tpdm_attr->idx >= drvdata->dsb_msr_num) 81 return -EINVAL; 82 return sysfs_emit(buf, "0x%x\n", 83 drvdata->dsb->msr[tpdm_attr->idx]); 84 case CMB_TRIG_PATT: 85 if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT) 86 return -EINVAL; 87 return sysfs_emit(buf, "0x%x\n", 88 drvdata->cmb->trig_patt[tpdm_attr->idx]); 89 case CMB_TRIG_PATT_MASK: 90 if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT) 91 return -EINVAL; 92 return sysfs_emit(buf, "0x%x\n", 93 drvdata->cmb->trig_patt_mask[tpdm_attr->idx]); 94 case CMB_PATT: 95 if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT) 96 return -EINVAL; 97 return sysfs_emit(buf, "0x%x\n", 98 drvdata->cmb->patt_val[tpdm_attr->idx]); 99 case CMB_PATT_MASK: 100 if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT) 101 return -EINVAL; 102 return sysfs_emit(buf, "0x%x\n", 103 drvdata->cmb->patt_mask[tpdm_attr->idx]); 104 case CMB_MSR: 105 if (tpdm_attr->idx >= drvdata->cmb_msr_num) 106 return -EINVAL; 107 return sysfs_emit(buf, "0x%x\n", 108 drvdata->cmb->msr[tpdm_attr->idx]); 109 } 110 return -EINVAL; 111 } 112 113 /* Write dataset array member with the index number */ 114 static ssize_t tpdm_simple_dataset_store(struct device *dev, 115 struct device_attribute *attr, 116 const char *buf, 117 size_t size) 118 { 119 unsigned long val; 120 ssize_t ret = -EINVAL; 121 122 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 123 struct tpdm_dataset_attribute *tpdm_attr = 124 container_of(attr, struct tpdm_dataset_attribute, attr); 125 126 if (kstrtoul(buf, 0, &val)) 127 return ret; 128 129 guard(spinlock)(&drvdata->spinlock); 130 switch (tpdm_attr->mem) { 131 case DSB_TRIG_PATT: 132 if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) { 133 drvdata->dsb->trig_patt[tpdm_attr->idx] = val; 134 ret = size; 135 } 136 break; 137 case DSB_TRIG_PATT_MASK: 138 if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) { 139 drvdata->dsb->trig_patt_mask[tpdm_attr->idx] = val; 140 ret = size; 141 } 142 break; 143 case DSB_PATT: 144 if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) { 145 drvdata->dsb->patt_val[tpdm_attr->idx] = val; 146 ret = size; 147 } 148 break; 149 case DSB_PATT_MASK: 150 if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) { 151 drvdata->dsb->patt_mask[tpdm_attr->idx] = val; 152 ret = size; 153 } 154 break; 155 case DSB_MSR: 156 if (tpdm_attr->idx < drvdata->dsb_msr_num) { 157 drvdata->dsb->msr[tpdm_attr->idx] = val; 158 ret = size; 159 } 160 break; 161 case CMB_TRIG_PATT: 162 if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) { 163 drvdata->cmb->trig_patt[tpdm_attr->idx] = val; 164 ret = size; 165 } 166 break; 167 case CMB_TRIG_PATT_MASK: 168 if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) { 169 drvdata->cmb->trig_patt_mask[tpdm_attr->idx] = val; 170 ret = size; 171 } 172 break; 173 case CMB_PATT: 174 if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) { 175 drvdata->cmb->patt_val[tpdm_attr->idx] = val; 176 ret = size; 177 } 178 break; 179 case CMB_PATT_MASK: 180 if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) { 181 drvdata->cmb->patt_mask[tpdm_attr->idx] = val; 182 ret = size; 183 } 184 break; 185 case CMB_MSR: 186 if (tpdm_attr->idx < drvdata->cmb_msr_num) { 187 drvdata->cmb->msr[tpdm_attr->idx] = val; 188 ret = size; 189 } 190 break; 191 default: 192 break; 193 } 194 195 return ret; 196 } 197 198 static umode_t tpdm_dsb_is_visible(struct kobject *kobj, 199 struct attribute *attr, int n) 200 { 201 struct device *dev = kobj_to_dev(kobj); 202 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 203 204 if (drvdata && tpdm_has_dsb_dataset(drvdata)) 205 return attr->mode; 206 207 return 0; 208 } 209 210 static umode_t tpdm_cmb_is_visible(struct kobject *kobj, 211 struct attribute *attr, int n) 212 { 213 struct device *dev = kobj_to_dev(kobj); 214 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 215 216 if (drvdata && drvdata->cmb) 217 return attr->mode; 218 219 return 0; 220 } 221 222 static umode_t tpdm_dsb_msr_is_visible(struct kobject *kobj, 223 struct attribute *attr, int n) 224 { 225 struct device *dev = kobj_to_dev(kobj); 226 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 227 struct device_attribute *dev_attr = 228 container_of(attr, struct device_attribute, attr); 229 struct tpdm_dataset_attribute *tpdm_attr = 230 container_of(dev_attr, struct tpdm_dataset_attribute, attr); 231 232 if (tpdm_attr->idx < drvdata->dsb_msr_num) 233 return attr->mode; 234 235 return 0; 236 } 237 238 static umode_t tpdm_cmb_msr_is_visible(struct kobject *kobj, 239 struct attribute *attr, int n) 240 { 241 struct device *dev = kobj_to_dev(kobj); 242 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 243 244 struct device_attribute *dev_attr = 245 container_of(attr, struct device_attribute, attr); 246 struct tpdm_dataset_attribute *tpdm_attr = 247 container_of(dev_attr, struct tpdm_dataset_attribute, attr); 248 249 if (tpdm_attr->idx < drvdata->cmb_msr_num) 250 return attr->mode; 251 252 return 0; 253 } 254 255 static umode_t tpdm_mcmb_is_visible(struct kobject *kobj, 256 struct attribute *attr, int n) 257 { 258 struct device *dev = kobj_to_dev(kobj); 259 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 260 261 if (drvdata && tpdm_has_mcmb_dataset(drvdata)) 262 return attr->mode; 263 264 return 0; 265 } 266 267 static void tpdm_reset_datasets(struct tpdm_drvdata *drvdata) 268 { 269 if (tpdm_has_dsb_dataset(drvdata)) { 270 memset(drvdata->dsb, 0, sizeof(struct dsb_dataset)); 271 272 drvdata->dsb->trig_ts = true; 273 drvdata->dsb->trig_type = false; 274 } 275 276 if (drvdata->cmb) 277 memset(drvdata->cmb, 0, sizeof(struct cmb_dataset)); 278 } 279 280 static void set_dsb_mode(struct tpdm_drvdata *drvdata, u32 *val) 281 { 282 u32 mode; 283 284 /* Set the test accurate mode */ 285 mode = TPDM_DSB_MODE_TEST(drvdata->dsb->mode); 286 *val &= ~TPDM_DSB_CR_TEST_MODE; 287 *val |= FIELD_PREP(TPDM_DSB_CR_TEST_MODE, mode); 288 289 /* Set the byte lane for high-performance mode */ 290 mode = TPDM_DSB_MODE_HPBYTESEL(drvdata->dsb->mode); 291 *val &= ~TPDM_DSB_CR_HPSEL; 292 *val |= FIELD_PREP(TPDM_DSB_CR_HPSEL, mode); 293 294 /* Set the performance mode */ 295 if (drvdata->dsb->mode & TPDM_DSB_MODE_PERF) 296 *val |= TPDM_DSB_CR_MODE; 297 else 298 *val &= ~TPDM_DSB_CR_MODE; 299 } 300 301 static void set_dsb_tier(struct tpdm_drvdata *drvdata) 302 { 303 u32 val; 304 305 val = readl_relaxed(drvdata->base + TPDM_DSB_TIER); 306 307 /* Clear all relevant fields */ 308 val &= ~(TPDM_DSB_TIER_PATT_TSENAB | TPDM_DSB_TIER_PATT_TYPE | 309 TPDM_DSB_TIER_XTRIG_TSENAB); 310 311 /* Set pattern timestamp type and enablement */ 312 if (drvdata->dsb->patt_ts) { 313 val |= TPDM_DSB_TIER_PATT_TSENAB; 314 if (drvdata->dsb->patt_type) 315 val |= TPDM_DSB_TIER_PATT_TYPE; 316 else 317 val &= ~TPDM_DSB_TIER_PATT_TYPE; 318 } else { 319 val &= ~TPDM_DSB_TIER_PATT_TSENAB; 320 } 321 322 /* Set trigger timestamp */ 323 if (drvdata->dsb->trig_ts) 324 val |= TPDM_DSB_TIER_XTRIG_TSENAB; 325 else 326 val &= ~TPDM_DSB_TIER_XTRIG_TSENAB; 327 328 writel_relaxed(val, drvdata->base + TPDM_DSB_TIER); 329 } 330 331 static void set_dsb_msr(struct tpdm_drvdata *drvdata) 332 { 333 int i; 334 335 for (i = 0; i < drvdata->dsb_msr_num; i++) 336 writel_relaxed(drvdata->dsb->msr[i], 337 drvdata->base + TPDM_DSB_MSR(i)); 338 } 339 340 static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata) 341 { 342 u32 val, i; 343 344 if (!tpdm_has_dsb_dataset(drvdata)) 345 return; 346 347 for (i = 0; i < TPDM_DSB_MAX_EDCR; i++) 348 writel_relaxed(drvdata->dsb->edge_ctrl[i], 349 drvdata->base + TPDM_DSB_EDCR(i)); 350 for (i = 0; i < TPDM_DSB_MAX_EDCMR; i++) 351 writel_relaxed(drvdata->dsb->edge_ctrl_mask[i], 352 drvdata->base + TPDM_DSB_EDCMR(i)); 353 for (i = 0; i < TPDM_DSB_MAX_PATT; i++) { 354 writel_relaxed(drvdata->dsb->patt_val[i], 355 drvdata->base + TPDM_DSB_TPR(i)); 356 writel_relaxed(drvdata->dsb->patt_mask[i], 357 drvdata->base + TPDM_DSB_TPMR(i)); 358 writel_relaxed(drvdata->dsb->trig_patt[i], 359 drvdata->base + TPDM_DSB_XPR(i)); 360 writel_relaxed(drvdata->dsb->trig_patt_mask[i], 361 drvdata->base + TPDM_DSB_XPMR(i)); 362 } 363 364 set_dsb_tier(drvdata); 365 set_dsb_msr(drvdata); 366 367 val = readl_relaxed(drvdata->base + TPDM_DSB_CR); 368 /* Set the mode of DSB dataset */ 369 set_dsb_mode(drvdata, &val); 370 /* Set trigger type */ 371 if (drvdata->dsb->trig_type) 372 val |= TPDM_DSB_CR_TRIG_TYPE; 373 else 374 val &= ~TPDM_DSB_CR_TRIG_TYPE; 375 /* Set the enable bit of DSB control register to 1 */ 376 val |= TPDM_DSB_CR_ENA; 377 writel_relaxed(val, drvdata->base + TPDM_DSB_CR); 378 } 379 380 static void set_cmb_tier(struct tpdm_drvdata *drvdata) 381 { 382 u32 val; 383 384 val = readl_relaxed(drvdata->base + TPDM_CMB_TIER); 385 386 /* Clear all relevant fields */ 387 val &= ~(TPDM_CMB_TIER_PATT_TSENAB | TPDM_CMB_TIER_TS_ALL | 388 TPDM_CMB_TIER_XTRIG_TSENAB); 389 390 /* Set pattern timestamp type and enablement */ 391 if (drvdata->cmb->patt_ts) 392 val |= TPDM_CMB_TIER_PATT_TSENAB; 393 394 /* Set trigger timestamp */ 395 if (drvdata->cmb->trig_ts) 396 val |= TPDM_CMB_TIER_XTRIG_TSENAB; 397 398 /* Set all timestamp enablement*/ 399 if (drvdata->cmb->ts_all) 400 val |= TPDM_CMB_TIER_TS_ALL; 401 402 writel_relaxed(val, drvdata->base + TPDM_CMB_TIER); 403 } 404 405 static void set_cmb_msr(struct tpdm_drvdata *drvdata) 406 { 407 int i; 408 409 for (i = 0; i < drvdata->cmb_msr_num; i++) 410 writel_relaxed(drvdata->cmb->msr[i], 411 drvdata->base + TPDM_CMB_MSR(i)); 412 } 413 414 static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata) 415 { 416 u32 val, i; 417 418 if (!drvdata->cmb) 419 return; 420 421 /* Configure pattern registers */ 422 for (i = 0; i < TPDM_CMB_MAX_PATT; i++) { 423 writel_relaxed(drvdata->cmb->patt_val[i], 424 drvdata->base + TPDM_CMB_TPR(i)); 425 writel_relaxed(drvdata->cmb->patt_mask[i], 426 drvdata->base + TPDM_CMB_TPMR(i)); 427 writel_relaxed(drvdata->cmb->trig_patt[i], 428 drvdata->base + TPDM_CMB_XPR(i)); 429 writel_relaxed(drvdata->cmb->trig_patt_mask[i], 430 drvdata->base + TPDM_CMB_XPMR(i)); 431 } 432 433 set_cmb_tier(drvdata); 434 set_cmb_msr(drvdata); 435 436 val = readl_relaxed(drvdata->base + TPDM_CMB_CR); 437 /* 438 * Set to 0 for continuous CMB collection mode, 439 * 1 for trace-on-change CMB collection mode. 440 */ 441 if (drvdata->cmb->trace_mode) 442 val |= TPDM_CMB_CR_MODE; 443 else 444 val &= ~TPDM_CMB_CR_MODE; 445 446 if (tpdm_has_mcmb_dataset(drvdata)) { 447 val &= ~TPDM_CMB_CR_XTRIG_LNSEL; 448 /* Set the lane participates in the output pattern */ 449 val |= FIELD_PREP(TPDM_CMB_CR_XTRIG_LNSEL, 450 drvdata->cmb->mcmb.trig_lane); 451 452 /* Set the enablement of the lane */ 453 val &= ~TPDM_CMB_CR_E_LN; 454 val |= FIELD_PREP(TPDM_CMB_CR_E_LN, 455 drvdata->cmb->mcmb.lane_select); 456 } 457 458 /* Set the enable bit of CMB control register to 1 */ 459 val |= TPDM_CMB_CR_ENA; 460 writel_relaxed(val, drvdata->base + TPDM_CMB_CR); 461 } 462 463 /* 464 * TPDM enable operations 465 * The TPDM or Monitor serves as data collection component for various 466 * dataset types. It covers Basic Counts(BC), Tenure Counts(TC), 467 * Continuous Multi-Bit(CMB), Multi-lane CMB(MCMB) and Discrete Single 468 * Bit(DSB). This function will initialize the configuration according 469 * to the dataset type supported by the TPDM. 470 */ 471 static void __tpdm_enable(struct tpdm_drvdata *drvdata) 472 { 473 CS_UNLOCK(drvdata->base); 474 475 tpdm_enable_dsb(drvdata); 476 tpdm_enable_cmb(drvdata); 477 478 CS_LOCK(drvdata->base); 479 } 480 481 static int tpdm_enable(struct coresight_device *csdev, struct perf_event *event, 482 enum cs_mode mode, 483 __maybe_unused struct coresight_path *path) 484 { 485 struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); 486 487 spin_lock(&drvdata->spinlock); 488 if (drvdata->enable) { 489 spin_unlock(&drvdata->spinlock); 490 return -EBUSY; 491 } 492 493 if (!coresight_take_mode(csdev, mode)) { 494 spin_unlock(&drvdata->spinlock); 495 return -EBUSY; 496 } 497 498 __tpdm_enable(drvdata); 499 drvdata->enable = true; 500 spin_unlock(&drvdata->spinlock); 501 502 dev_dbg(drvdata->dev, "TPDM tracing enabled\n"); 503 return 0; 504 } 505 506 static void tpdm_disable_dsb(struct tpdm_drvdata *drvdata) 507 { 508 u32 val; 509 510 if (!tpdm_has_dsb_dataset(drvdata)) 511 return; 512 513 /* Set the enable bit of DSB control register to 0 */ 514 val = readl_relaxed(drvdata->base + TPDM_DSB_CR); 515 val &= ~TPDM_DSB_CR_ENA; 516 writel_relaxed(val, drvdata->base + TPDM_DSB_CR); 517 } 518 519 static void tpdm_disable_cmb(struct tpdm_drvdata *drvdata) 520 { 521 u32 val; 522 523 if (!drvdata->cmb) 524 return; 525 526 val = readl_relaxed(drvdata->base + TPDM_CMB_CR); 527 /* Set the enable bit of CMB control register to 0 */ 528 val &= ~TPDM_CMB_CR_ENA; 529 writel_relaxed(val, drvdata->base + TPDM_CMB_CR); 530 } 531 532 /* TPDM disable operations */ 533 static void __tpdm_disable(struct tpdm_drvdata *drvdata) 534 { 535 CS_UNLOCK(drvdata->base); 536 537 tpdm_disable_dsb(drvdata); 538 tpdm_disable_cmb(drvdata); 539 540 CS_LOCK(drvdata->base); 541 } 542 543 static void tpdm_disable(struct coresight_device *csdev, 544 struct perf_event *event) 545 { 546 struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); 547 548 spin_lock(&drvdata->spinlock); 549 if (!drvdata->enable) { 550 spin_unlock(&drvdata->spinlock); 551 return; 552 } 553 554 __tpdm_disable(drvdata); 555 coresight_set_mode(csdev, CS_MODE_DISABLED); 556 drvdata->enable = false; 557 spin_unlock(&drvdata->spinlock); 558 559 dev_dbg(drvdata->dev, "TPDM tracing disabled\n"); 560 } 561 562 static const struct coresight_ops_source tpdm_source_ops = { 563 .enable = tpdm_enable, 564 .disable = tpdm_disable, 565 }; 566 567 static const struct coresight_ops tpdm_cs_ops = { 568 .source_ops = &tpdm_source_ops, 569 }; 570 571 static int tpdm_datasets_setup(struct tpdm_drvdata *drvdata) 572 { 573 u32 pidr; 574 575 /* Get the datasets present on the TPDM. */ 576 pidr = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR0); 577 drvdata->datasets |= pidr & GENMASK(TPDM_DATASETS - 1, 0); 578 579 if (tpdm_has_dsb_dataset(drvdata) && (!drvdata->dsb)) { 580 drvdata->dsb = devm_kzalloc(drvdata->dev, 581 sizeof(*drvdata->dsb), GFP_KERNEL); 582 if (!drvdata->dsb) 583 return -ENOMEM; 584 } 585 if ((tpdm_has_cmb_dataset(drvdata) || tpdm_has_mcmb_dataset(drvdata)) 586 && (!drvdata->cmb)) { 587 drvdata->cmb = devm_kzalloc(drvdata->dev, 588 sizeof(*drvdata->cmb), GFP_KERNEL); 589 if (!drvdata->cmb) 590 return -ENOMEM; 591 } 592 593 tpdm_reset_datasets(drvdata); 594 595 return 0; 596 } 597 598 static ssize_t reset_dataset_store(struct device *dev, 599 struct device_attribute *attr, 600 const char *buf, 601 size_t size) 602 { 603 int ret = 0; 604 unsigned long val; 605 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 606 607 ret = kstrtoul(buf, 0, &val); 608 if (ret || val != 1) 609 return -EINVAL; 610 611 spin_lock(&drvdata->spinlock); 612 tpdm_reset_datasets(drvdata); 613 spin_unlock(&drvdata->spinlock); 614 615 return size; 616 } 617 static DEVICE_ATTR_WO(reset_dataset); 618 619 /* 620 * value 1: 64 bits test data 621 * value 2: 32 bits test data 622 */ 623 static ssize_t integration_test_store(struct device *dev, 624 struct device_attribute *attr, 625 const char *buf, 626 size_t size) 627 { 628 int i, ret = 0; 629 unsigned long val; 630 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 631 632 ret = kstrtoul(buf, 10, &val); 633 if (ret) 634 return ret; 635 636 if (val != 1 && val != 2) 637 return -EINVAL; 638 639 if (!drvdata->enable) 640 return -EINVAL; 641 642 if (val == 1) 643 val = ATBCNTRL_VAL_64; 644 else 645 val = ATBCNTRL_VAL_32; 646 CS_UNLOCK(drvdata->base); 647 writel_relaxed(0x1, drvdata->base + TPDM_ITCNTRL); 648 649 for (i = 0; i < INTEGRATION_TEST_CYCLE; i++) 650 writel_relaxed(val, drvdata->base + TPDM_ITATBCNTRL); 651 652 writel_relaxed(0, drvdata->base + TPDM_ITCNTRL); 653 CS_LOCK(drvdata->base); 654 return size; 655 } 656 static DEVICE_ATTR_WO(integration_test); 657 658 static struct attribute *tpdm_attrs[] = { 659 &dev_attr_reset_dataset.attr, 660 &dev_attr_integration_test.attr, 661 NULL, 662 }; 663 664 static struct attribute_group tpdm_attr_grp = { 665 .attrs = tpdm_attrs, 666 }; 667 668 static ssize_t dsb_mode_show(struct device *dev, 669 struct device_attribute *attr, 670 char *buf) 671 { 672 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 673 674 return sysfs_emit(buf, "%x\n", drvdata->dsb->mode); 675 } 676 677 static ssize_t dsb_mode_store(struct device *dev, 678 struct device_attribute *attr, 679 const char *buf, 680 size_t size) 681 { 682 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 683 unsigned long val; 684 685 if ((kstrtoul(buf, 0, &val)) || (val & ~TPDM_DSB_MODE_MASK)) 686 return -EINVAL; 687 688 spin_lock(&drvdata->spinlock); 689 drvdata->dsb->mode = val & TPDM_DSB_MODE_MASK; 690 spin_unlock(&drvdata->spinlock); 691 return size; 692 } 693 static DEVICE_ATTR_RW(dsb_mode); 694 695 static ssize_t ctrl_idx_show(struct device *dev, 696 struct device_attribute *attr, 697 char *buf) 698 { 699 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 700 701 return sysfs_emit(buf, "%u\n", 702 (unsigned int)drvdata->dsb->edge_ctrl_idx); 703 } 704 705 /* 706 * The EDCR registers can include up to 16 32-bit registers, and each 707 * one can be configured to control up to 16 edge detections(2 bits 708 * control one edge detection). So a total 256 edge detections can be 709 * configured. This function provides a way to set the index number of 710 * the edge detection which needs to be configured. 711 */ 712 static ssize_t ctrl_idx_store(struct device *dev, 713 struct device_attribute *attr, 714 const char *buf, 715 size_t size) 716 { 717 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 718 unsigned long val; 719 720 if ((kstrtoul(buf, 0, &val)) || (val >= TPDM_DSB_MAX_LINES)) 721 return -EINVAL; 722 723 spin_lock(&drvdata->spinlock); 724 drvdata->dsb->edge_ctrl_idx = val; 725 spin_unlock(&drvdata->spinlock); 726 727 return size; 728 } 729 static DEVICE_ATTR_RW(ctrl_idx); 730 731 /* 732 * This function is used to control the edge detection according 733 * to the index number that has been set. 734 * "edge_ctrl" should be one of the following values. 735 * 0 - Rising edge detection 736 * 1 - Falling edge detection 737 * 2 - Rising and falling edge detection (toggle detection) 738 */ 739 static ssize_t ctrl_val_store(struct device *dev, 740 struct device_attribute *attr, 741 const char *buf, 742 size_t size) 743 { 744 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 745 unsigned long val, edge_ctrl; 746 int reg; 747 748 if ((kstrtoul(buf, 0, &edge_ctrl)) || (edge_ctrl > 0x2)) 749 return -EINVAL; 750 751 spin_lock(&drvdata->spinlock); 752 /* 753 * There are 2 bit per DSB Edge Control line. 754 * Thus we have 16 lines in a 32bit word. 755 */ 756 reg = EDCR_TO_WORD_IDX(drvdata->dsb->edge_ctrl_idx); 757 val = drvdata->dsb->edge_ctrl[reg]; 758 val &= ~EDCR_TO_WORD_MASK(drvdata->dsb->edge_ctrl_idx); 759 val |= EDCR_TO_WORD_VAL(edge_ctrl, drvdata->dsb->edge_ctrl_idx); 760 drvdata->dsb->edge_ctrl[reg] = val; 761 spin_unlock(&drvdata->spinlock); 762 763 return size; 764 } 765 static DEVICE_ATTR_WO(ctrl_val); 766 767 static ssize_t ctrl_mask_store(struct device *dev, 768 struct device_attribute *attr, 769 const char *buf, 770 size_t size) 771 { 772 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 773 unsigned long val; 774 u32 set; 775 int reg; 776 777 if ((kstrtoul(buf, 0, &val)) || (val & ~1UL)) 778 return -EINVAL; 779 780 spin_lock(&drvdata->spinlock); 781 /* 782 * There is 1 bit per DSB Edge Control Mark line. 783 * Thus we have 32 lines in a 32bit word. 784 */ 785 reg = EDCMR_TO_WORD_IDX(drvdata->dsb->edge_ctrl_idx); 786 set = drvdata->dsb->edge_ctrl_mask[reg]; 787 if (val) 788 set |= BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx)); 789 else 790 set &= ~BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx)); 791 drvdata->dsb->edge_ctrl_mask[reg] = set; 792 spin_unlock(&drvdata->spinlock); 793 794 return size; 795 } 796 static DEVICE_ATTR_WO(ctrl_mask); 797 798 static ssize_t enable_ts_show(struct device *dev, 799 struct device_attribute *attr, 800 char *buf) 801 { 802 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 803 struct tpdm_dataset_attribute *tpdm_attr = 804 container_of(attr, struct tpdm_dataset_attribute, attr); 805 ssize_t size = -EINVAL; 806 807 if (tpdm_attr->mem == DSB_PATT) 808 size = sysfs_emit(buf, "%u\n", 809 (unsigned int)drvdata->dsb->patt_ts); 810 else if (tpdm_attr->mem == CMB_PATT) 811 size = sysfs_emit(buf, "%u\n", 812 (unsigned int)drvdata->cmb->patt_ts); 813 814 return size; 815 } 816 817 /* 818 * value 1: Enable/Disable DSB pattern timestamp 819 */ 820 static ssize_t enable_ts_store(struct device *dev, 821 struct device_attribute *attr, 822 const char *buf, 823 size_t size) 824 { 825 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 826 struct tpdm_dataset_attribute *tpdm_attr = 827 container_of(attr, struct tpdm_dataset_attribute, attr); 828 unsigned long val; 829 830 if ((kstrtoul(buf, 0, &val)) || (val & ~1UL)) 831 return -EINVAL; 832 833 guard(spinlock)(&drvdata->spinlock); 834 if (tpdm_attr->mem == DSB_PATT) 835 drvdata->dsb->patt_ts = !!val; 836 else if (tpdm_attr->mem == CMB_PATT) 837 drvdata->cmb->patt_ts = !!val; 838 else 839 return -EINVAL; 840 841 return size; 842 } 843 844 static ssize_t set_type_show(struct device *dev, 845 struct device_attribute *attr, 846 char *buf) 847 { 848 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 849 850 return sysfs_emit(buf, "%u\n", 851 (unsigned int)drvdata->dsb->patt_type); 852 } 853 854 /* 855 * value 1: Set DSB pattern type 856 */ 857 static ssize_t set_type_store(struct device *dev, 858 struct device_attribute *attr, 859 const char *buf, size_t size) 860 { 861 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 862 unsigned long val; 863 864 if ((kstrtoul(buf, 0, &val)) || (val & ~1UL)) 865 return -EINVAL; 866 867 spin_lock(&drvdata->spinlock); 868 drvdata->dsb->patt_type = val; 869 spin_unlock(&drvdata->spinlock); 870 return size; 871 } 872 static DEVICE_ATTR_RW(set_type); 873 874 static ssize_t dsb_trig_type_show(struct device *dev, 875 struct device_attribute *attr, char *buf) 876 { 877 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 878 879 return sysfs_emit(buf, "%u\n", 880 (unsigned int)drvdata->dsb->trig_type); 881 } 882 883 /* 884 * Trigger type (boolean): 885 * false - Disable trigger type. 886 * true - Enable trigger type. 887 */ 888 static ssize_t dsb_trig_type_store(struct device *dev, 889 struct device_attribute *attr, 890 const char *buf, 891 size_t size) 892 { 893 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 894 unsigned long val; 895 896 if ((kstrtoul(buf, 0, &val)) || (val & ~1UL)) 897 return -EINVAL; 898 899 spin_lock(&drvdata->spinlock); 900 if (val) 901 drvdata->dsb->trig_type = true; 902 else 903 drvdata->dsb->trig_type = false; 904 spin_unlock(&drvdata->spinlock); 905 return size; 906 } 907 static DEVICE_ATTR_RW(dsb_trig_type); 908 909 static ssize_t dsb_trig_ts_show(struct device *dev, 910 struct device_attribute *attr, 911 char *buf) 912 { 913 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 914 915 return sysfs_emit(buf, "%u\n", 916 (unsigned int)drvdata->dsb->trig_ts); 917 } 918 919 /* 920 * Trigger timestamp (boolean): 921 * false - Disable trigger timestamp. 922 * true - Enable trigger timestamp. 923 */ 924 static ssize_t dsb_trig_ts_store(struct device *dev, 925 struct device_attribute *attr, 926 const char *buf, 927 size_t size) 928 { 929 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 930 unsigned long val; 931 932 if ((kstrtoul(buf, 0, &val)) || (val & ~1UL)) 933 return -EINVAL; 934 935 spin_lock(&drvdata->spinlock); 936 if (val) 937 drvdata->dsb->trig_ts = true; 938 else 939 drvdata->dsb->trig_ts = false; 940 spin_unlock(&drvdata->spinlock); 941 return size; 942 } 943 static DEVICE_ATTR_RW(dsb_trig_ts); 944 945 static ssize_t cmb_mode_show(struct device *dev, 946 struct device_attribute *attr, 947 char *buf) 948 { 949 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 950 951 return sysfs_emit(buf, "%x\n", drvdata->cmb->trace_mode); 952 953 } 954 955 static ssize_t cmb_mode_store(struct device *dev, 956 struct device_attribute *attr, 957 const char *buf, 958 size_t size) 959 { 960 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 961 unsigned long trace_mode; 962 963 if (kstrtoul(buf, 0, &trace_mode) || (trace_mode & ~1UL)) 964 return -EINVAL; 965 966 spin_lock(&drvdata->spinlock); 967 drvdata->cmb->trace_mode = trace_mode; 968 spin_unlock(&drvdata->spinlock); 969 return size; 970 } 971 static DEVICE_ATTR_RW(cmb_mode); 972 973 static ssize_t cmb_ts_all_show(struct device *dev, 974 struct device_attribute *attr, 975 char *buf) 976 { 977 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 978 979 return sysfs_emit(buf, "%u\n", 980 (unsigned int)drvdata->cmb->ts_all); 981 } 982 983 static ssize_t cmb_ts_all_store(struct device *dev, 984 struct device_attribute *attr, 985 const char *buf, 986 size_t size) 987 { 988 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 989 unsigned long val; 990 991 if ((kstrtoul(buf, 0, &val)) || (val & ~1UL)) 992 return -EINVAL; 993 994 guard(spinlock)(&drvdata->spinlock); 995 if (val) 996 drvdata->cmb->ts_all = true; 997 else 998 drvdata->cmb->ts_all = false; 999 1000 return size; 1001 } 1002 static DEVICE_ATTR_RW(cmb_ts_all); 1003 1004 static ssize_t cmb_trig_ts_show(struct device *dev, 1005 struct device_attribute *attr, 1006 char *buf) 1007 { 1008 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 1009 1010 return sysfs_emit(buf, "%u\n", 1011 (unsigned int)drvdata->cmb->trig_ts); 1012 } 1013 1014 static ssize_t cmb_trig_ts_store(struct device *dev, 1015 struct device_attribute *attr, 1016 const char *buf, 1017 size_t size) 1018 { 1019 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 1020 unsigned long val; 1021 1022 if ((kstrtoul(buf, 0, &val)) || (val & ~1UL)) 1023 return -EINVAL; 1024 1025 guard(spinlock)(&drvdata->spinlock); 1026 if (val) 1027 drvdata->cmb->trig_ts = true; 1028 else 1029 drvdata->cmb->trig_ts = false; 1030 1031 return size; 1032 } 1033 static DEVICE_ATTR_RW(cmb_trig_ts); 1034 1035 static ssize_t mcmb_trig_lane_show(struct device *dev, 1036 struct device_attribute *attr, 1037 char *buf) 1038 { 1039 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 1040 1041 return sysfs_emit(buf, "%u\n", 1042 (unsigned int)drvdata->cmb->mcmb.trig_lane); 1043 } 1044 1045 static ssize_t mcmb_trig_lane_store(struct device *dev, 1046 struct device_attribute *attr, 1047 const char *buf, 1048 size_t size) 1049 { 1050 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 1051 unsigned long val; 1052 1053 if ((kstrtoul(buf, 0, &val)) || (val >= TPDM_MCMB_MAX_LANES)) 1054 return -EINVAL; 1055 1056 guard(spinlock)(&drvdata->spinlock); 1057 drvdata->cmb->mcmb.trig_lane = val; 1058 1059 return size; 1060 } 1061 static DEVICE_ATTR_RW(mcmb_trig_lane); 1062 1063 static ssize_t mcmb_lanes_select_show(struct device *dev, 1064 struct device_attribute *attr, 1065 char *buf) 1066 { 1067 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 1068 1069 return sysfs_emit(buf, "%u\n", 1070 (unsigned int)drvdata->cmb->mcmb.lane_select); 1071 } 1072 1073 static ssize_t mcmb_lanes_select_store(struct device *dev, 1074 struct device_attribute *attr, 1075 const char *buf, 1076 size_t size) 1077 { 1078 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 1079 unsigned long val; 1080 1081 if (kstrtoul(buf, 0, &val) || (val & ~TPDM_MCMB_E_LN_MASK)) 1082 return -EINVAL; 1083 1084 guard(spinlock)(&drvdata->spinlock); 1085 drvdata->cmb->mcmb.lane_select = val & TPDM_MCMB_E_LN_MASK; 1086 1087 return size; 1088 } 1089 static DEVICE_ATTR_RW(mcmb_lanes_select); 1090 1091 static struct attribute *tpdm_dsb_edge_attrs[] = { 1092 &dev_attr_ctrl_idx.attr, 1093 &dev_attr_ctrl_val.attr, 1094 &dev_attr_ctrl_mask.attr, 1095 DSB_EDGE_CTRL_ATTR(0), 1096 DSB_EDGE_CTRL_ATTR(1), 1097 DSB_EDGE_CTRL_ATTR(2), 1098 DSB_EDGE_CTRL_ATTR(3), 1099 DSB_EDGE_CTRL_ATTR(4), 1100 DSB_EDGE_CTRL_ATTR(5), 1101 DSB_EDGE_CTRL_ATTR(6), 1102 DSB_EDGE_CTRL_ATTR(7), 1103 DSB_EDGE_CTRL_ATTR(8), 1104 DSB_EDGE_CTRL_ATTR(9), 1105 DSB_EDGE_CTRL_ATTR(10), 1106 DSB_EDGE_CTRL_ATTR(11), 1107 DSB_EDGE_CTRL_ATTR(12), 1108 DSB_EDGE_CTRL_ATTR(13), 1109 DSB_EDGE_CTRL_ATTR(14), 1110 DSB_EDGE_CTRL_ATTR(15), 1111 DSB_EDGE_CTRL_MASK_ATTR(0), 1112 DSB_EDGE_CTRL_MASK_ATTR(1), 1113 DSB_EDGE_CTRL_MASK_ATTR(2), 1114 DSB_EDGE_CTRL_MASK_ATTR(3), 1115 DSB_EDGE_CTRL_MASK_ATTR(4), 1116 DSB_EDGE_CTRL_MASK_ATTR(5), 1117 DSB_EDGE_CTRL_MASK_ATTR(6), 1118 DSB_EDGE_CTRL_MASK_ATTR(7), 1119 NULL, 1120 }; 1121 1122 static struct attribute *tpdm_dsb_trig_patt_attrs[] = { 1123 DSB_TRIG_PATT_ATTR(0), 1124 DSB_TRIG_PATT_ATTR(1), 1125 DSB_TRIG_PATT_ATTR(2), 1126 DSB_TRIG_PATT_ATTR(3), 1127 DSB_TRIG_PATT_ATTR(4), 1128 DSB_TRIG_PATT_ATTR(5), 1129 DSB_TRIG_PATT_ATTR(6), 1130 DSB_TRIG_PATT_ATTR(7), 1131 DSB_TRIG_PATT_MASK_ATTR(0), 1132 DSB_TRIG_PATT_MASK_ATTR(1), 1133 DSB_TRIG_PATT_MASK_ATTR(2), 1134 DSB_TRIG_PATT_MASK_ATTR(3), 1135 DSB_TRIG_PATT_MASK_ATTR(4), 1136 DSB_TRIG_PATT_MASK_ATTR(5), 1137 DSB_TRIG_PATT_MASK_ATTR(6), 1138 DSB_TRIG_PATT_MASK_ATTR(7), 1139 NULL, 1140 }; 1141 1142 static struct attribute *tpdm_dsb_patt_attrs[] = { 1143 DSB_PATT_ATTR(0), 1144 DSB_PATT_ATTR(1), 1145 DSB_PATT_ATTR(2), 1146 DSB_PATT_ATTR(3), 1147 DSB_PATT_ATTR(4), 1148 DSB_PATT_ATTR(5), 1149 DSB_PATT_ATTR(6), 1150 DSB_PATT_ATTR(7), 1151 DSB_PATT_MASK_ATTR(0), 1152 DSB_PATT_MASK_ATTR(1), 1153 DSB_PATT_MASK_ATTR(2), 1154 DSB_PATT_MASK_ATTR(3), 1155 DSB_PATT_MASK_ATTR(4), 1156 DSB_PATT_MASK_ATTR(5), 1157 DSB_PATT_MASK_ATTR(6), 1158 DSB_PATT_MASK_ATTR(7), 1159 DSB_PATT_ENABLE_TS, 1160 &dev_attr_set_type.attr, 1161 NULL, 1162 }; 1163 1164 static struct attribute *tpdm_dsb_msr_attrs[] = { 1165 DSB_MSR_ATTR(0), 1166 DSB_MSR_ATTR(1), 1167 DSB_MSR_ATTR(2), 1168 DSB_MSR_ATTR(3), 1169 DSB_MSR_ATTR(4), 1170 DSB_MSR_ATTR(5), 1171 DSB_MSR_ATTR(6), 1172 DSB_MSR_ATTR(7), 1173 DSB_MSR_ATTR(8), 1174 DSB_MSR_ATTR(9), 1175 DSB_MSR_ATTR(10), 1176 DSB_MSR_ATTR(11), 1177 DSB_MSR_ATTR(12), 1178 DSB_MSR_ATTR(13), 1179 DSB_MSR_ATTR(14), 1180 DSB_MSR_ATTR(15), 1181 DSB_MSR_ATTR(16), 1182 DSB_MSR_ATTR(17), 1183 DSB_MSR_ATTR(18), 1184 DSB_MSR_ATTR(19), 1185 DSB_MSR_ATTR(20), 1186 DSB_MSR_ATTR(21), 1187 DSB_MSR_ATTR(22), 1188 DSB_MSR_ATTR(23), 1189 DSB_MSR_ATTR(24), 1190 DSB_MSR_ATTR(25), 1191 DSB_MSR_ATTR(26), 1192 DSB_MSR_ATTR(27), 1193 DSB_MSR_ATTR(28), 1194 DSB_MSR_ATTR(29), 1195 DSB_MSR_ATTR(30), 1196 DSB_MSR_ATTR(31), 1197 NULL, 1198 }; 1199 1200 static struct attribute *tpdm_cmb_trig_patt_attrs[] = { 1201 CMB_TRIG_PATT_ATTR(0), 1202 CMB_TRIG_PATT_ATTR(1), 1203 CMB_TRIG_PATT_MASK_ATTR(0), 1204 CMB_TRIG_PATT_MASK_ATTR(1), 1205 NULL, 1206 }; 1207 1208 static struct attribute *tpdm_cmb_patt_attrs[] = { 1209 CMB_PATT_ATTR(0), 1210 CMB_PATT_ATTR(1), 1211 CMB_PATT_MASK_ATTR(0), 1212 CMB_PATT_MASK_ATTR(1), 1213 CMB_PATT_ENABLE_TS, 1214 NULL, 1215 }; 1216 1217 static struct attribute *tpdm_cmb_msr_attrs[] = { 1218 CMB_MSR_ATTR(0), 1219 CMB_MSR_ATTR(1), 1220 CMB_MSR_ATTR(2), 1221 CMB_MSR_ATTR(3), 1222 CMB_MSR_ATTR(4), 1223 CMB_MSR_ATTR(5), 1224 CMB_MSR_ATTR(6), 1225 CMB_MSR_ATTR(7), 1226 CMB_MSR_ATTR(8), 1227 CMB_MSR_ATTR(9), 1228 CMB_MSR_ATTR(10), 1229 CMB_MSR_ATTR(11), 1230 CMB_MSR_ATTR(12), 1231 CMB_MSR_ATTR(13), 1232 CMB_MSR_ATTR(14), 1233 CMB_MSR_ATTR(15), 1234 CMB_MSR_ATTR(16), 1235 CMB_MSR_ATTR(17), 1236 CMB_MSR_ATTR(18), 1237 CMB_MSR_ATTR(19), 1238 CMB_MSR_ATTR(20), 1239 CMB_MSR_ATTR(21), 1240 CMB_MSR_ATTR(22), 1241 CMB_MSR_ATTR(23), 1242 CMB_MSR_ATTR(24), 1243 CMB_MSR_ATTR(25), 1244 CMB_MSR_ATTR(26), 1245 CMB_MSR_ATTR(27), 1246 CMB_MSR_ATTR(28), 1247 CMB_MSR_ATTR(29), 1248 CMB_MSR_ATTR(30), 1249 CMB_MSR_ATTR(31), 1250 NULL, 1251 }; 1252 1253 static struct attribute *tpdm_mcmb_attrs[] = { 1254 &dev_attr_mcmb_trig_lane.attr, 1255 &dev_attr_mcmb_lanes_select.attr, 1256 NULL, 1257 }; 1258 1259 static struct attribute *tpdm_dsb_attrs[] = { 1260 &dev_attr_dsb_mode.attr, 1261 &dev_attr_dsb_trig_ts.attr, 1262 &dev_attr_dsb_trig_type.attr, 1263 NULL, 1264 }; 1265 1266 static struct attribute *tpdm_cmb_attrs[] = { 1267 &dev_attr_cmb_mode.attr, 1268 &dev_attr_cmb_ts_all.attr, 1269 &dev_attr_cmb_trig_ts.attr, 1270 NULL, 1271 }; 1272 1273 static struct attribute_group tpdm_dsb_attr_grp = { 1274 .attrs = tpdm_dsb_attrs, 1275 .is_visible = tpdm_dsb_is_visible, 1276 }; 1277 1278 static struct attribute_group tpdm_dsb_edge_grp = { 1279 .attrs = tpdm_dsb_edge_attrs, 1280 .is_visible = tpdm_dsb_is_visible, 1281 .name = "dsb_edge", 1282 }; 1283 1284 static struct attribute_group tpdm_dsb_trig_patt_grp = { 1285 .attrs = tpdm_dsb_trig_patt_attrs, 1286 .is_visible = tpdm_dsb_is_visible, 1287 .name = "dsb_trig_patt", 1288 }; 1289 1290 static struct attribute_group tpdm_dsb_patt_grp = { 1291 .attrs = tpdm_dsb_patt_attrs, 1292 .is_visible = tpdm_dsb_is_visible, 1293 .name = "dsb_patt", 1294 }; 1295 1296 static struct attribute_group tpdm_dsb_msr_grp = { 1297 .attrs = tpdm_dsb_msr_attrs, 1298 .is_visible = tpdm_dsb_msr_is_visible, 1299 .name = "dsb_msr", 1300 }; 1301 1302 static struct attribute_group tpdm_cmb_attr_grp = { 1303 .attrs = tpdm_cmb_attrs, 1304 .is_visible = tpdm_cmb_is_visible, 1305 }; 1306 1307 static struct attribute_group tpdm_cmb_trig_patt_grp = { 1308 .attrs = tpdm_cmb_trig_patt_attrs, 1309 .is_visible = tpdm_cmb_is_visible, 1310 .name = "cmb_trig_patt", 1311 }; 1312 1313 static struct attribute_group tpdm_cmb_patt_grp = { 1314 .attrs = tpdm_cmb_patt_attrs, 1315 .is_visible = tpdm_cmb_is_visible, 1316 .name = "cmb_patt", 1317 }; 1318 1319 static struct attribute_group tpdm_cmb_msr_grp = { 1320 .attrs = tpdm_cmb_msr_attrs, 1321 .is_visible = tpdm_cmb_msr_is_visible, 1322 .name = "cmb_msr", 1323 }; 1324 1325 static struct attribute_group tpdm_mcmb_attr_grp = { 1326 .attrs = tpdm_mcmb_attrs, 1327 .is_visible = tpdm_mcmb_is_visible, 1328 }; 1329 1330 static const struct attribute_group *tpdm_attr_grps[] = { 1331 &tpdm_attr_grp, 1332 &tpdm_dsb_attr_grp, 1333 &tpdm_dsb_edge_grp, 1334 &tpdm_dsb_trig_patt_grp, 1335 &tpdm_dsb_patt_grp, 1336 &tpdm_dsb_msr_grp, 1337 &tpdm_cmb_attr_grp, 1338 &tpdm_cmb_trig_patt_grp, 1339 &tpdm_cmb_patt_grp, 1340 &tpdm_cmb_msr_grp, 1341 &tpdm_mcmb_attr_grp, 1342 NULL, 1343 }; 1344 1345 static int tpdm_probe(struct amba_device *adev, const struct amba_id *id) 1346 { 1347 void __iomem *base; 1348 struct device *dev = &adev->dev; 1349 struct coresight_platform_data *pdata; 1350 struct tpdm_drvdata *drvdata; 1351 struct coresight_desc desc = { 0 }; 1352 int ret; 1353 1354 pdata = coresight_get_platform_data(dev); 1355 if (IS_ERR(pdata)) 1356 return PTR_ERR(pdata); 1357 adev->dev.platform_data = pdata; 1358 1359 /* driver data*/ 1360 drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); 1361 if (!drvdata) 1362 return -ENOMEM; 1363 drvdata->dev = &adev->dev; 1364 dev_set_drvdata(dev, drvdata); 1365 1366 base = devm_ioremap_resource(dev, &adev->res); 1367 if (IS_ERR(base)) 1368 return PTR_ERR(base); 1369 1370 drvdata->base = base; 1371 1372 ret = tpdm_datasets_setup(drvdata); 1373 if (ret) 1374 return ret; 1375 1376 if (drvdata && tpdm_has_dsb_dataset(drvdata)) 1377 of_property_read_u32(drvdata->dev->of_node, 1378 "qcom,dsb-msrs-num", &drvdata->dsb_msr_num); 1379 1380 if (drvdata && tpdm_has_cmb_dataset(drvdata)) 1381 of_property_read_u32(drvdata->dev->of_node, 1382 "qcom,cmb-msrs-num", &drvdata->cmb_msr_num); 1383 1384 /* Set up coresight component description */ 1385 desc.name = coresight_alloc_device_name(&tpdm_devs, dev); 1386 if (!desc.name) 1387 return -ENOMEM; 1388 desc.type = CORESIGHT_DEV_TYPE_SOURCE; 1389 desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM; 1390 desc.ops = &tpdm_cs_ops; 1391 desc.pdata = adev->dev.platform_data; 1392 desc.dev = &adev->dev; 1393 desc.access = CSDEV_ACCESS_IOMEM(base); 1394 desc.groups = tpdm_attr_grps; 1395 drvdata->csdev = coresight_register(&desc); 1396 if (IS_ERR(drvdata->csdev)) 1397 return PTR_ERR(drvdata->csdev); 1398 1399 spin_lock_init(&drvdata->spinlock); 1400 1401 /* Decrease pm refcount when probe is done.*/ 1402 pm_runtime_put(&adev->dev); 1403 1404 return 0; 1405 } 1406 1407 static void tpdm_remove(struct amba_device *adev) 1408 { 1409 struct tpdm_drvdata *drvdata = dev_get_drvdata(&adev->dev); 1410 1411 coresight_unregister(drvdata->csdev); 1412 } 1413 1414 /* 1415 * Different TPDM has different periph id. 1416 * The difference is 0-7 bits' value. So ignore 0-7 bits. 1417 */ 1418 static const struct amba_id tpdm_ids[] = { 1419 { 1420 .id = 0x001f0e00, 1421 .mask = 0x00ffff00, 1422 }, 1423 { 0, 0, NULL }, 1424 }; 1425 1426 static struct amba_driver tpdm_driver = { 1427 .drv = { 1428 .name = "coresight-tpdm", 1429 .suppress_bind_attrs = true, 1430 }, 1431 .probe = tpdm_probe, 1432 .id_table = tpdm_ids, 1433 .remove = tpdm_remove, 1434 }; 1435 1436 module_amba_driver(tpdm_driver); 1437 1438 MODULE_LICENSE("GPL"); 1439 MODULE_DESCRIPTION("Trace, Profiling & Diagnostic Monitor driver"); 1440