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