FILE
coresight-etm3x-core.c
File preview with syntax highlighting.
linux-6.19.14/drivers/hwtracing/coresight/coresight-etm3x-core.c
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. 4 * 5 * Description: CoreSight Program Flow Trace driver 6 */ 7 8#include <linux/kernel.h> 9#include <linux/moduleparam.h> 10#include <linux/init.h> 11#include <linux/types.h> 12#include <linux/device.h> 13#include <linux/io.h> 14#include <linux/err.h> 15#include <linux/fs.h> 16#include <linux/slab.h> 17#include <linux/delay.h> 18#include <linux/smp.h> 19#include <linux/sysfs.h> 20#include <linux/stat.h> 21#include <linux/pm_runtime.h> 22#include <linux/cpu.h> 23#include <linux/of.h> 24#include <linux/coresight.h> 25#include <linux/coresight-pmu.h> 26#include <linux/amba/bus.h> 27#include <linux/seq_file.h> 28#include <linux/uaccess.h> 29#include <linux/clk.h> 30#include <linux/perf_event.h> 31#include <asm/sections.h> 32 33#include "coresight-etm.h" 34#include "coresight-etm-perf.h" 35#include "coresight-trace-id.h" 36 37/* 38 * Not really modular but using module_param is the easiest way to 39 * remain consistent with existing use cases for now. 40 */ 41static int boot_enable; 42module_param_named(boot_enable, boot_enable, int, S_IRUGO); 43 44static struct etm_drvdata *etmdrvdata[NR_CPUS]; 45 46static enum cpuhp_state hp_online; 47 48/* 49 * Memory mapped writes to clear os lock are not supported on some processors 50 * and OS lock must be unlocked before any memory mapped access on such 51 * processors, otherwise memory mapped reads/writes will be invalid. 52 */ 53static void etm_os_unlock(struct etm_drvdata *drvdata) 54{ 55 /* Writing any value to ETMOSLAR unlocks the trace registers */ 56 etm_writel(drvdata, 0x0, ETMOSLAR); 57 drvdata->os_unlock = true; 58 isb(); 59} 60 61static void etm_set_pwrdwn(struct etm_drvdata *drvdata) 62{ 63 u32 etmcr; 64 65 /* Ensure pending cp14 accesses complete before setting pwrdwn */ 66 mb(); 67 isb(); 68 etmcr = etm_readl(drvdata, ETMCR); 69 etmcr |= ETMCR_PWD_DWN; 70 etm_writel(drvdata, etmcr, ETMCR); 71} 72 73static void etm_clr_pwrdwn(struct etm_drvdata *drvdata) 74{ 75 u32 etmcr; 76 77 etmcr = etm_readl(drvdata, ETMCR); 78 etmcr &= ~ETMCR_PWD_DWN; 79 etm_writel(drvdata, etmcr, ETMCR); 80 /* Ensure pwrup completes before subsequent cp14 accesses */ 81 mb(); 82 isb(); 83} 84 85static void etm_set_pwrup(struct etm_drvdata *drvdata) 86{ 87 u32 etmpdcr; 88 89 etmpdcr = readl_relaxed(drvdata->csa.base + ETMPDCR); 90 etmpdcr |= ETMPDCR_PWD_UP; 91 writel_relaxed(etmpdcr, drvdata->csa.base + ETMPDCR); 92 /* Ensure pwrup completes before subsequent cp14 accesses */ 93 mb(); 94 isb(); 95} 96 97static void etm_clr_pwrup(struct etm_drvdata *drvdata) 98{ 99 u32 etmpdcr; 100 101 /* Ensure pending cp14 accesses complete before clearing pwrup */ 102 mb(); 103 isb(); 104 etmpdcr = readl_relaxed(drvdata->csa.base + ETMPDCR); 105 etmpdcr &= ~ETMPDCR_PWD_UP; 106 writel_relaxed(etmpdcr, drvdata->csa.base + ETMPDCR); 107} 108 109/** 110 * coresight_timeout_etm - loop until a bit has changed to a specific state. 111 * @drvdata: etm's private data structure. 112 * @offset: address of a register, starting from @addr. 113 * @position: the position of the bit of interest. 114 * @value: the value the bit should have. 115 * 116 * Basically the same as @coresight_timeout except for the register access 117 * method where we have to account for CP14 configurations. 118 * 119 * Return: 0 as soon as the bit has taken the desired state or -EAGAIN if 120 * TIMEOUT_US has elapsed, which ever happens first. 121 */ 122 123static int coresight_timeout_etm(struct etm_drvdata *drvdata, u32 offset, 124 int position, int value) 125{ 126 int i; 127 u32 val; 128 129 for (i = TIMEOUT_US; i > 0; i--) { 130 val = etm_readl(drvdata, offset); 131 /* Waiting on the bit to go from 0 to 1 */ 132 if (value) { 133 if (val & BIT(position)) 134 return 0; 135 /* Waiting on the bit to go from 1 to 0 */ 136 } else { 137 if (!(val & BIT(position))) 138 return 0; 139 } 140 141 /* 142 * Delay is arbitrary - the specification doesn't say how long 143 * we are expected to wait. Extra check required to make sure 144 * we don't wait needlessly on the last iteration. 145 */ 146 if (i - 1) 147 udelay(1); 148 } 149 150 return -EAGAIN; 151} 152 153 154static void etm_set_prog(struct etm_drvdata *drvdata) 155{ 156 u32 etmcr; 157 158 etmcr = etm_readl(drvdata, ETMCR); 159 etmcr |= ETMCR_ETM_PRG; 160 etm_writel(drvdata, etmcr, ETMCR); 161 /* 162 * Recommended by spec for cp14 accesses to ensure etmcr write is 163 * complete before polling etmsr 164 */ 165 isb(); 166 if (coresight_timeout_etm(drvdata, ETMSR, ETMSR_PROG_BIT, 1)) { 167 dev_err(&drvdata->csdev->dev, 168 "%s: timeout observed when probing at offset %#x\n", 169 __func__, ETMSR); 170 } 171} 172 173static void etm_clr_prog(struct etm_drvdata *drvdata) 174{ 175 u32 etmcr; 176 177 etmcr = etm_readl(drvdata, ETMCR); 178 etmcr &= ~ETMCR_ETM_PRG; 179 etm_writel(drvdata, etmcr, ETMCR); 180 /* 181 * Recommended by spec for cp14 accesses to ensure etmcr write is 182 * complete before polling etmsr 183 */ 184 isb(); 185 if (coresight_timeout_etm(drvdata, ETMSR, ETMSR_PROG_BIT, 0)) { 186 dev_err(&drvdata->csdev->dev, 187 "%s: timeout observed when probing at offset %#x\n", 188 __func__, ETMSR); 189 } 190} 191 192void etm_set_default(struct etm_config *config) 193{ 194 int i; 195 196 if (WARN_ON_ONCE(!config)) 197 return; 198 199 /* 200 * Taken verbatim from the TRM: 201 * 202 * To trace all memory: 203 * set bit [24] in register 0x009, the ETMTECR1, to 1 204 * set all other bits in register 0x009, the ETMTECR1, to 0 205 * set all bits in register 0x007, the ETMTECR2, to 0 206 * set register 0x008, the ETMTEEVR, to 0x6F (TRUE). 207 */ 208 config->enable_ctrl1 = ETMTECR1_INC_EXC; 209 config->enable_ctrl2 = 0x0; 210 config->enable_event = ETM_HARD_WIRE_RES_A; 211 212 config->trigger_event = ETM_DEFAULT_EVENT_VAL; 213 config->enable_event = ETM_HARD_WIRE_RES_A; 214 215 config->seq_12_event = ETM_DEFAULT_EVENT_VAL; 216 config->seq_21_event = ETM_DEFAULT_EVENT_VAL; 217 config->seq_23_event = ETM_DEFAULT_EVENT_VAL; 218 config->seq_31_event = ETM_DEFAULT_EVENT_VAL; 219 config->seq_32_event = ETM_DEFAULT_EVENT_VAL; 220 config->seq_13_event = ETM_DEFAULT_EVENT_VAL; 221 config->timestamp_event = ETM_DEFAULT_EVENT_VAL; 222 223 for (i = 0; i < ETM_MAX_CNTR; i++) { 224 config->cntr_rld_val[i] = 0x0; 225 config->cntr_event[i] = ETM_DEFAULT_EVENT_VAL; 226 config->cntr_rld_event[i] = ETM_DEFAULT_EVENT_VAL; 227 config->cntr_val[i] = 0x0; 228 } 229 230 config->seq_curr_state = 0x0; 231 config->ctxid_idx = 0x0; 232 for (i = 0; i < ETM_MAX_CTXID_CMP; i++) 233 config->ctxid_pid[i] = 0x0; 234 235 config->ctxid_mask = 0x0; 236 /* Setting default to 1024 as per TRM recommendation */ 237 config->sync_freq = 0x400; 238} 239 240void etm_config_trace_mode(struct etm_config *config) 241{ 242 u32 flags, mode; 243 244 mode = config->mode; 245 246 mode &= (ETM_MODE_EXCL_KERN | ETM_MODE_EXCL_USER); 247 248 /* excluding kernel AND user space doesn't make sense */ 249 if (mode == (ETM_MODE_EXCL_KERN | ETM_MODE_EXCL_USER)) 250 return; 251 252 /* nothing to do if neither flags are set */ 253 if (!(mode & ETM_MODE_EXCL_KERN) && !(mode & ETM_MODE_EXCL_USER)) 254 return; 255 256 flags = (1 << 0 | /* instruction execute */ 257 3 << 3 | /* ARM instruction */ 258 0 << 5 | /* No data value comparison */ 259 0 << 7 | /* No exact mach */ 260 0 << 8); /* Ignore context ID */ 261 262 /* No need to worry about single address comparators. */ 263 config->enable_ctrl2 = 0x0; 264 265 /* Bit 0 is address range comparator 1 */ 266 config->enable_ctrl1 = ETMTECR1_ADDR_COMP_1; 267 268 /* 269 * On ETMv3.5: 270 * ETMACTRn[13,11] == Non-secure state comparison control 271 * ETMACTRn[12,10] == Secure state comparison control 272 * 273 * b00 == Match in all modes in this state 274 * b01 == Do not match in any more in this state 275 * b10 == Match in all modes excepts user mode in this state 276 * b11 == Match only in user mode in this state 277 */ 278 279 /* Tracing in secure mode is not supported at this time */ 280 flags |= (0 << 12 | 1 << 10); 281 282 if (mode & ETM_MODE_EXCL_USER) { 283 /* exclude user, match all modes except user mode */ 284 flags |= (1 << 13 | 0 << 11); 285 } else { 286 /* exclude kernel, match only in user mode */ 287 flags |= (1 << 13 | 1 << 11); 288 } 289 290 /* 291 * The ETMEEVR register is already set to "hard wire A". As such 292 * all there is to do is setup an address comparator that spans 293 * the entire address range and configure the state and mode bits. 294 */ 295 config->addr_val[0] = (u32) 0x0; 296 config->addr_val[1] = (u32) ~0x0; 297 config->addr_acctype[0] = flags; 298 config->addr_acctype[1] = flags; 299 config->addr_type[0] = ETM_ADDR_TYPE_RANGE; 300 config->addr_type[1] = ETM_ADDR_TYPE_RANGE; 301} 302 303#define ETM3X_SUPPORTED_OPTIONS (ETMCR_CYC_ACC | \ 304 ETMCR_TIMESTAMP_EN | \ 305 ETMCR_RETURN_STACK) 306 307static int etm_parse_event_config(struct etm_drvdata *drvdata, 308 struct perf_event *event) 309{ 310 struct etm_config *config = &drvdata->config; 311 struct perf_event_attr *attr = &event->attr; 312 313 if (!attr) 314 return -EINVAL; 315 316 /* Clear configuration from previous run */ 317 memset(config, 0, sizeof(struct etm_config)); 318 319 if (attr->exclude_kernel) 320 config->mode = ETM_MODE_EXCL_KERN; 321 322 if (attr->exclude_user) 323 config->mode = ETM_MODE_EXCL_USER; 324 325 /* Always start from the default config */ 326 etm_set_default(config); 327 328 /* 329 * By default the tracers are configured to trace the whole address 330 * range. Narrow the field only if requested by user space. 331 */ 332 if (config->mode) 333 etm_config_trace_mode(config); 334 335 /* 336 * At this time only cycle accurate, return stack and timestamp 337 * options are available. 338 */ 339 if (attr->config & ~ETM3X_SUPPORTED_OPTIONS) 340 return -EINVAL; 341 342 config->ctrl = attr->config; 343 344 /* Don't trace contextID when runs in non-root PID namespace */ 345 if (!task_is_in_init_pid_ns(current)) 346 config->ctrl &= ~ETMCR_CTXID_SIZE; 347 348 /* 349 * Possible to have cores with PTM (supports ret stack) and ETM 350 * (never has ret stack) on the same SoC. So if we have a request 351 * for return stack that can't be honoured on this core then 352 * clear the bit - trace will still continue normally 353 */ 354 if ((config->ctrl & ETMCR_RETURN_STACK) && 355 !(drvdata->etmccer & ETMCCER_RETSTACK)) 356 config->ctrl &= ~ETMCR_RETURN_STACK; 357 358 return 0; 359} 360 361static int etm_enable_hw(struct etm_drvdata *drvdata) 362{ 363 int i, rc; 364 u32 etmcr; 365 struct etm_config *config = &drvdata->config; 366 struct coresight_device *csdev = drvdata->csdev; 367 368 CS_UNLOCK(drvdata->csa.base); 369 370 rc = coresight_claim_device_unlocked(csdev); 371 if (rc) 372 goto done; 373 374 /* Turn engine on */ 375 etm_clr_pwrdwn(drvdata); 376 /* Apply power to trace registers */ 377 etm_set_pwrup(drvdata); 378 /* Make sure all registers are accessible */ 379 etm_os_unlock(drvdata); 380 381 etm_set_prog(drvdata); 382 383 etmcr = etm_readl(drvdata, ETMCR); 384 /* Clear setting from a previous run if need be */ 385 etmcr &= ~ETM3X_SUPPORTED_OPTIONS; 386 etmcr |= drvdata->port_size; 387 etmcr |= ETMCR_ETM_EN; 388 etm_writel(drvdata, config->ctrl | etmcr, ETMCR); 389 etm_writel(drvdata, config->trigger_event, ETMTRIGGER); 390 etm_writel(drvdata, config->startstop_ctrl, ETMTSSCR); 391 etm_writel(drvdata, config->enable_event, ETMTEEVR); 392 etm_writel(drvdata, config->enable_ctrl1, ETMTECR1); 393 etm_writel(drvdata, config->fifofull_level, ETMFFLR); 394 for (i = 0; i < drvdata->nr_addr_cmp; i++) { 395 etm_writel(drvdata, config->addr_val[i], ETMACVRn(i)); 396 etm_writel(drvdata, config->addr_acctype[i], ETMACTRn(i)); 397 } 398 for (i = 0; i < drvdata->nr_cntr; i++) { 399 etm_writel(drvdata, config->cntr_rld_val[i], ETMCNTRLDVRn(i)); 400 etm_writel(drvdata, config->cntr_event[i], ETMCNTENRn(i)); 401 etm_writel(drvdata, config->cntr_rld_event[i], 402 ETMCNTRLDEVRn(i)); 403 etm_writel(drvdata, config->cntr_val[i], ETMCNTVRn(i)); 404 } 405 etm_writel(drvdata, config->seq_12_event, ETMSQ12EVR); 406 etm_writel(drvdata, config->seq_21_event, ETMSQ21EVR); 407 etm_writel(drvdata, config->seq_23_event, ETMSQ23EVR); 408 etm_writel(drvdata, config->seq_31_event, ETMSQ31EVR); 409 etm_writel(drvdata, config->seq_32_event, ETMSQ32EVR); 410 etm_writel(drvdata, config->seq_13_event, ETMSQ13EVR); 411 etm_writel(drvdata, config->seq_curr_state, ETMSQR); 412 for (i = 0; i < drvdata->nr_ext_out; i++) 413 etm_writel(drvdata, ETM_DEFAULT_EVENT_VAL, ETMEXTOUTEVRn(i)); 414 for (i = 0; i < drvdata->nr_ctxid_cmp; i++) 415 etm_writel(drvdata, config->ctxid_pid[i], ETMCIDCVRn(i)); 416 etm_writel(drvdata, config->ctxid_mask, ETMCIDCMR); 417 etm_writel(drvdata, config->sync_freq, ETMSYNCFR); 418 /* No external input selected */ 419 etm_writel(drvdata, 0x0, ETMEXTINSELR); 420 etm_writel(drvdata, config->timestamp_event, ETMTSEVR); 421 /* No auxiliary control selected */ 422 etm_writel(drvdata, 0x0, ETMAUXCR); 423 etm_writel(drvdata, drvdata->traceid, ETMTRACEIDR); 424 /* No VMID comparator value selected */ 425 etm_writel(drvdata, 0x0, ETMVMIDCVR); 426 427 etm_clr_prog(drvdata); 428 429done: 430 CS_LOCK(drvdata->csa.base); 431 432 dev_dbg(&drvdata->csdev->dev, "cpu: %d enable smp call done: %d\n", 433 drvdata->cpu, rc); 434 return rc; 435} 436 437struct etm_enable_arg { 438 struct etm_drvdata *drvdata; 439 int rc; 440}; 441 442static void etm_enable_sysfs_smp_call(void *info) 443{ 444 struct etm_enable_arg *arg = info; 445 struct coresight_device *csdev; 446 447 if (WARN_ON(!arg)) 448 return; 449 450 csdev = arg->drvdata->csdev; 451 if (!coresight_take_mode(csdev, CS_MODE_SYSFS)) { 452 /* Someone is already using the tracer */ 453 arg->rc = -EBUSY; 454 return; 455 } 456 457 arg->rc = etm_enable_hw(arg->drvdata); 458 459 /* The tracer didn't start */ 460 if (arg->rc) 461 coresight_set_mode(csdev, CS_MODE_DISABLED); 462} 463 464static int etm_cpu_id(struct coresight_device *csdev) 465{ 466 struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); 467 468 return drvdata->cpu; 469} 470 471void etm_release_trace_id(struct etm_drvdata *drvdata) 472{ 473 coresight_trace_id_put_cpu_id(drvdata->cpu); 474} 475 476static int etm_enable_perf(struct coresight_device *csdev, 477 struct perf_event *event, 478 struct coresight_path *path) 479{ 480 struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); 481 int ret; 482 483 if (WARN_ON_ONCE(drvdata->cpu != smp_processor_id())) 484 return -EINVAL; 485 486 if (!coresight_take_mode(csdev, CS_MODE_PERF)) 487 return -EBUSY; 488 489 /* Configure the tracer based on the session's specifics */ 490 etm_parse_event_config(drvdata, event); 491 drvdata->traceid = path->trace_id; 492 493 /* And enable it */ 494 ret = etm_enable_hw(drvdata); 495 496 /* Failed to start tracer; roll back to DISABLED mode */ 497 if (ret) 498 coresight_set_mode(csdev, CS_MODE_DISABLED); 499 500 return ret; 501} 502 503static int etm_enable_sysfs(struct coresight_device *csdev, struct coresight_path *path) 504{ 505 struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); 506 struct etm_enable_arg arg = { }; 507 int ret; 508 509 spin_lock(&drvdata->spinlock); 510 511 drvdata->traceid = path->trace_id; 512 513 /* 514 * Configure the ETM only if the CPU is online. If it isn't online 515 * hw configuration will take place on the local CPU during bring up. 516 */ 517 if (cpu_online(drvdata->cpu)) { 518 arg.drvdata = drvdata; 519 ret = smp_call_function_single(drvdata->cpu, 520 etm_enable_sysfs_smp_call, &arg, 1); 521 if (!ret) 522 ret = arg.rc; 523 if (!ret) 524 drvdata->sticky_enable = true; 525 } else { 526 ret = -ENODEV; 527 } 528 529 if (ret) 530 etm_release_trace_id(drvdata); 531 532 spin_unlock(&drvdata->spinlock); 533 534 if (!ret) 535 dev_dbg(&csdev->dev, "ETM tracing enabled\n"); 536 return ret; 537} 538 539static int etm_enable(struct coresight_device *csdev, struct perf_event *event, 540 enum cs_mode mode, struct coresight_path *path) 541{ 542 int ret; 543 544 switch (mode) { 545 case CS_MODE_SYSFS: 546 ret = etm_enable_sysfs(csdev, path); 547 break; 548 case CS_MODE_PERF: 549 ret = etm_enable_perf(csdev, event, path); 550 break; 551 default: 552 ret = -EINVAL; 553 } 554 555 return ret; 556} 557 558static void etm_disable_hw(struct etm_drvdata *drvdata) 559{ 560 int i; 561 struct etm_config *config = &drvdata->config; 562 struct coresight_device *csdev = drvdata->csdev; 563 564 CS_UNLOCK(drvdata->csa.base); 565 etm_set_prog(drvdata); 566 567 /* Read back sequencer and counters for post trace analysis */ 568 config->seq_curr_state = (etm_readl(drvdata, ETMSQR) & ETM_SQR_MASK); 569 570 for (i = 0; i < drvdata->nr_cntr; i++) 571 config->cntr_val[i] = etm_readl(drvdata, ETMCNTVRn(i)); 572 573 etm_set_pwrdwn(drvdata); 574 coresight_disclaim_device_unlocked(csdev); 575 576 CS_LOCK(drvdata->csa.base); 577 578 dev_dbg(&drvdata->csdev->dev, 579 "cpu: %d disable smp call done\n", drvdata->cpu); 580} 581 582static void etm_disable_sysfs_smp_call(void *info) 583{ 584 struct etm_drvdata *drvdata = info; 585 586 etm_disable_hw(drvdata); 587 588 coresight_set_mode(drvdata->csdev, CS_MODE_DISABLED); 589} 590 591static void etm_disable_perf(struct coresight_device *csdev) 592{ 593 struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); 594 595 if (WARN_ON_ONCE(drvdata->cpu != smp_processor_id())) 596 return; 597 598 CS_UNLOCK(drvdata->csa.base); 599 600 /* Setting the prog bit disables tracing immediately */ 601 etm_set_prog(drvdata); 602 603 /* 604 * There is no way to know when the tracer will be used again so 605 * power down the tracer. 606 */ 607 etm_set_pwrdwn(drvdata); 608 coresight_disclaim_device_unlocked(csdev); 609 610 CS_LOCK(drvdata->csa.base); 611 612 coresight_set_mode(drvdata->csdev, CS_MODE_DISABLED); 613 614 /* 615 * perf will release trace ids when _free_aux() 616 * is called at the end of the session 617 */ 618 619} 620 621static void etm_disable_sysfs(struct coresight_device *csdev) 622{ 623 struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); 624 625 /* 626 * Taking hotplug lock here protects from clocks getting disabled 627 * with tracing being left on (crash scenario) if user disable occurs 628 * after cpu online mask indicates the cpu is offline but before the 629 * DYING hotplug callback is serviced by the ETM driver. 630 */ 631 cpus_read_lock(); 632 spin_lock(&drvdata->spinlock); 633 634 /* 635 * Executing etm_disable_hw on the cpu whose ETM is being disabled 636 * ensures that register writes occur when cpu is powered. 637 */ 638 smp_call_function_single(drvdata->cpu, etm_disable_sysfs_smp_call, 639 drvdata, 1); 640 641 spin_unlock(&drvdata->spinlock); 642 cpus_read_unlock(); 643 644 /* 645 * we only release trace IDs when resetting sysfs. 646 * This permits sysfs users to read the trace ID after the trace 647 * session has completed. This maintains operational behaviour with 648 * prior trace id allocation method 649 */ 650 651 dev_dbg(&csdev->dev, "ETM tracing disabled\n"); 652} 653 654static void etm_disable(struct coresight_device *csdev, 655 struct perf_event *event) 656{ 657 enum cs_mode mode; 658 659 /* 660 * For as long as the tracer isn't disabled another entity can't 661 * change its status. As such we can read the status here without 662 * fearing it will change under us. 663 */ 664 mode = coresight_get_mode(csdev); 665 666 switch (mode) { 667 case CS_MODE_DISABLED: 668 break; 669 case CS_MODE_SYSFS: 670 etm_disable_sysfs(csdev); 671 break; 672 case CS_MODE_PERF: 673 etm_disable_perf(csdev); 674 break; 675 default: 676 WARN_ON_ONCE(mode); 677 return; 678 } 679} 680 681static const struct coresight_ops_source etm_source_ops = { 682 .cpu_id = etm_cpu_id, 683 .enable = etm_enable, 684 .disable = etm_disable, 685}; 686 687static const struct coresight_ops etm_cs_ops = { 688 .trace_id = coresight_etm_get_trace_id, 689 .source_ops = &etm_source_ops, 690}; 691 692static int etm_online_cpu(unsigned int cpu) 693{ 694 if (!etmdrvdata[cpu]) 695 return 0; 696 697 if (etmdrvdata[cpu]->boot_enable && !etmdrvdata[cpu]->sticky_enable) 698 coresight_enable_sysfs(etmdrvdata[cpu]->csdev); 699 return 0; 700} 701 702static int etm_starting_cpu(unsigned int cpu) 703{ 704 if (!etmdrvdata[cpu]) 705 return 0; 706 707 spin_lock(&etmdrvdata[cpu]->spinlock); 708 if (!etmdrvdata[cpu]->os_unlock) { 709 etm_os_unlock(etmdrvdata[cpu]); 710 etmdrvdata[cpu]->os_unlock = true; 711 } 712 713 if (coresight_get_mode(etmdrvdata[cpu]->csdev)) 714 etm_enable_hw(etmdrvdata[cpu]); 715 spin_unlock(&etmdrvdata[cpu]->spinlock); 716 return 0; 717} 718 719static int etm_dying_cpu(unsigned int cpu) 720{ 721 if (!etmdrvdata[cpu]) 722 return 0; 723 724 spin_lock(&etmdrvdata[cpu]->spinlock); 725 if (coresight_get_mode(etmdrvdata[cpu]->csdev)) 726 etm_disable_hw(etmdrvdata[cpu]); 727 spin_unlock(&etmdrvdata[cpu]->spinlock); 728 return 0; 729} 730 731static bool etm_arch_supported(u8 arch) 732{ 733 switch (arch) { 734 case ETM_ARCH_V3_3: 735 break; 736 case ETM_ARCH_V3_5: 737 break; 738 case PFT_ARCH_V1_0: 739 break; 740 case PFT_ARCH_V1_1: 741 break; 742 default: 743 return false; 744 } 745 return true; 746} 747 748static void etm_init_arch_data(void *info) 749{ 750 u32 etmidr; 751 u32 etmccr; 752 struct etm_drvdata *drvdata = info; 753 754 /* Make sure all registers are accessible */ 755 etm_os_unlock(drvdata); 756 757 CS_UNLOCK(drvdata->csa.base); 758 759 /* First dummy read */ 760 (void)etm_readl(drvdata, ETMPDSR); 761 /* Provide power to ETM: ETMPDCR[3] == 1 */ 762 etm_set_pwrup(drvdata); 763 /* 764 * Clear power down bit since when this bit is set writes to 765 * certain registers might be ignored. 766 */ 767 etm_clr_pwrdwn(drvdata); 768 /* 769 * Set prog bit. It will be set from reset but this is included to 770 * ensure it is set 771 */ 772 etm_set_prog(drvdata); 773 774 /* Find all capabilities */ 775 etmidr = etm_readl(drvdata, ETMIDR); 776 drvdata->arch = BMVAL(etmidr, 4, 11); 777 drvdata->port_size = etm_readl(drvdata, ETMCR) & PORT_SIZE_MASK; 778 779 drvdata->etmccer = etm_readl(drvdata, ETMCCER); 780 etmccr = etm_readl(drvdata, ETMCCR); 781 drvdata->etmccr = etmccr; 782 drvdata->nr_addr_cmp = BMVAL(etmccr, 0, 3) * 2; 783 drvdata->nr_cntr = BMVAL(etmccr, 13, 15); 784 drvdata->nr_ext_inp = BMVAL(etmccr, 17, 19); 785 drvdata->nr_ext_out = BMVAL(etmccr, 20, 22); 786 drvdata->nr_ctxid_cmp = BMVAL(etmccr, 24, 25); 787 788 coresight_clear_self_claim_tag_unlocked(&drvdata->csa); 789 etm_set_pwrdwn(drvdata); 790 etm_clr_pwrup(drvdata); 791 CS_LOCK(drvdata->csa.base); 792} 793 794static int __init etm_hp_setup(void) 795{ 796 int ret; 797 798 ret = cpuhp_setup_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING, 799 "arm/coresight:starting", 800 etm_starting_cpu, etm_dying_cpu); 801 802 if (ret) 803 return ret; 804 805 ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, 806 "arm/coresight:online", 807 etm_online_cpu, NULL); 808 809 /* HP dyn state ID returned in ret on success */ 810 if (ret > 0) { 811 hp_online = ret; 812 return 0; 813 } 814 815 /* failed dyn state - remove others */ 816 cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING); 817 818 return ret; 819} 820 821static void etm_hp_clear(void) 822{ 823 cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING); 824 if (hp_online) { 825 cpuhp_remove_state_nocalls(hp_online); 826 hp_online = 0; 827 } 828} 829 830static int etm_probe(struct amba_device *adev, const struct amba_id *id) 831{ 832 int ret; 833 void __iomem *base; 834 struct device *dev = &adev->dev; 835 struct coresight_platform_data *pdata = NULL; 836 struct etm_drvdata *drvdata; 837 struct resource *res = &adev->res; 838 struct coresight_desc desc = { 0 }; 839 840 drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); 841 if (!drvdata) 842 return -ENOMEM; 843 844 drvdata->use_cp14 = fwnode_property_read_bool(dev->fwnode, "arm,cp14"); 845 dev_set_drvdata(dev, drvdata); 846 847 /* Validity for the resource is already checked by the AMBA core */ 848 base = devm_ioremap_resource(dev, res); 849 if (IS_ERR(base)) 850 return PTR_ERR(base); 851 852 desc.access = drvdata->csa = CSDEV_ACCESS_IOMEM(base); 853 854 spin_lock_init(&drvdata->spinlock); 855 856 drvdata->atclk = devm_clk_get_optional_enabled(dev, "atclk"); 857 if (IS_ERR(drvdata->atclk)) 858 return PTR_ERR(drvdata->atclk); 859 860 drvdata->cpu = coresight_get_cpu(dev); 861 if (drvdata->cpu < 0) 862 return drvdata->cpu; 863 864 desc.name = devm_kasprintf(dev, GFP_KERNEL, "etm%d", drvdata->cpu); 865 if (!desc.name) 866 return -ENOMEM; 867 868 if (smp_call_function_single(drvdata->cpu, 869 etm_init_arch_data, drvdata, 1)) 870 dev_err(dev, "ETM arch init failed\n"); 871 872 if (etm_arch_supported(drvdata->arch) == false) 873 return -EINVAL; 874 875 etm_set_default(&drvdata->config); 876 877 pdata = coresight_get_platform_data(dev); 878 if (IS_ERR(pdata)) 879 return PTR_ERR(pdata); 880 881 adev->dev.platform_data = pdata; 882 883 desc.type = CORESIGHT_DEV_TYPE_SOURCE; 884 desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_PROC; 885 desc.ops = &etm_cs_ops; 886 desc.pdata = pdata; 887 desc.dev = dev; 888 desc.groups = coresight_etm_groups; 889 drvdata->csdev = coresight_register(&desc); 890 if (IS_ERR(drvdata->csdev)) 891 return PTR_ERR(drvdata->csdev); 892 893 ret = etm_perf_symlink(drvdata->csdev, true); 894 if (ret) { 895 coresight_unregister(drvdata->csdev); 896 return ret; 897 } 898 899 etmdrvdata[drvdata->cpu] = drvdata; 900 901 pm_runtime_put(&adev->dev); 902 dev_info(&drvdata->csdev->dev, 903 "%s initialized\n", (char *)coresight_get_uci_data(id)); 904 if (boot_enable) { 905 coresight_enable_sysfs(drvdata->csdev); 906 drvdata->boot_enable = true; 907 } 908 909 return 0; 910} 911 912static void clear_etmdrvdata(void *info) 913{ 914 int cpu = *(int *)info; 915 916 etmdrvdata[cpu] = NULL; 917} 918 919static void etm_remove(struct amba_device *adev) 920{ 921 struct etm_drvdata *drvdata = dev_get_drvdata(&adev->dev); 922 923 etm_perf_symlink(drvdata->csdev, false); 924 925 /* 926 * Taking hotplug lock here to avoid racing between etm_remove and 927 * CPU hotplug call backs. 928 */ 929 cpus_read_lock(); 930 /* 931 * The readers for etmdrvdata[] are CPU hotplug call backs 932 * and PM notification call backs. Change etmdrvdata[i] on 933 * CPU i ensures these call backs has consistent view 934 * inside one call back function. 935 */ 936 if (smp_call_function_single(drvdata->cpu, clear_etmdrvdata, &drvdata->cpu, 1)) 937 etmdrvdata[drvdata->cpu] = NULL; 938 939 cpus_read_unlock(); 940 941 coresight_unregister(drvdata->csdev); 942} 943 944#ifdef CONFIG_PM 945static int etm_runtime_suspend(struct device *dev) 946{ 947 struct etm_drvdata *drvdata = dev_get_drvdata(dev); 948 949 clk_disable_unprepare(drvdata->atclk); 950 951 return 0; 952} 953 954static int etm_runtime_resume(struct device *dev) 955{ 956 struct etm_drvdata *drvdata = dev_get_drvdata(dev); 957 958 return clk_prepare_enable(drvdata->atclk); 959} 960#endif 961 962static const struct dev_pm_ops etm_dev_pm_ops = { 963 SET_RUNTIME_PM_OPS(etm_runtime_suspend, etm_runtime_resume, NULL) 964}; 965 966static const struct amba_id etm_ids[] = { 967 /* ETM 3.3 */ 968 CS_AMBA_ID_DATA(0x000bb921, "ETM 3.3"), 969 /* ETM 3.5 - Cortex-A5 */ 970 CS_AMBA_ID_DATA(0x000bb955, "ETM 3.5"), 971 /* ETM 3.5 */ 972 CS_AMBA_ID_DATA(0x000bb956, "ETM 3.5"), 973 /* PTM 1.0 */ 974 CS_AMBA_ID_DATA(0x000bb950, "PTM 1.0"), 975 /* PTM 1.1 */ 976 CS_AMBA_ID_DATA(0x000bb95f, "PTM 1.1"), 977 /* PTM 1.1 Qualcomm */ 978 CS_AMBA_ID_DATA(0x000b006f, "PTM 1.1"), 979 { 0, 0, NULL}, 980}; 981 982MODULE_DEVICE_TABLE(amba, etm_ids); 983 984static struct amba_driver etm_driver = { 985 .drv = { 986 .name = "coresight-etm3x", 987 .pm = &etm_dev_pm_ops, 988 .suppress_bind_attrs = true, 989 }, 990 .probe = etm_probe, 991 .remove = etm_remove, 992 .id_table = etm_ids, 993}; 994 995static int __init etm_init(void) 996{ 997 int ret; 998 999 ret = etm_hp_setup(); 1000 1001 /* etm_hp_setup() does its own cleanup - exit on error */ 1002 if (ret) 1003 return ret; 1004 1005 ret = amba_driver_register(&etm_driver); 1006 if (ret) { 1007 pr_err("Error registering etm3x driver\n"); 1008 etm_hp_clear(); 1009 } 1010 1011 return ret; 1012} 1013 1014static void __exit etm_exit(void) 1015{ 1016 amba_driver_unregister(&etm_driver); 1017 etm_hp_clear(); 1018} 1019 1020module_init(etm_init); 1021module_exit(etm_exit); 1022 1023MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>"); 1024MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>"); 1025MODULE_DESCRIPTION("Arm CoreSight Program Flow Trace driver"); 1026MODULE_LICENSE("GPL v2");
~/
Read-only file preview.