1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Intel SOC Telemetry Platform Driver: Currently supports APL 4 * Copyright (c) 2015, Intel Corporation. 5 * All Rights Reserved. 6 * 7 * This file provides the platform specific telemetry implementation for APL. 8 * It used the PUNIT and PMC IPC interfaces for configuring the counters. 9 * The accumulated results are fetched from SRAM. 10 */ 11 12 #include <linux/io.h> 13 #include <linux/module.h> 14 #include <linux/platform_device.h> 15 16 #include <asm/cpu_device_id.h> 17 #include <asm/intel-family.h> 18 #include <asm/intel_punit_ipc.h> 19 #include <asm/intel_telemetry.h> 20 21 #define DRIVER_NAME "intel_telemetry" 22 #define DRIVER_VERSION "1.0.0" 23 24 #define TELEM_TRC_VERBOSITY_MASK 0x3 25 26 #define TELEM_MIN_PERIOD(x) ((x) & 0x7F0000) 27 #define TELEM_MAX_PERIOD(x) ((x) & 0x7F000000) 28 #define TELEM_SAMPLE_PERIOD_INVALID(x) ((x) & (BIT(7))) 29 #define TELEM_CLEAR_SAMPLE_PERIOD(x) ((x) &= ~0x7F) 30 31 #define TELEM_SAMPLING_DEFAULT_PERIOD 0xD 32 33 #define TELEM_MAX_EVENTS_SRAM 28 34 #define TELEM_SSRAM_STARTTIME_OFFSET 8 35 #define TELEM_SSRAM_EVTLOG_OFFSET 16 36 37 #define IOSS_TELEM 0xeb 38 #define IOSS_TELEM_EVENT_READ 0x0 39 #define IOSS_TELEM_EVENT_WRITE 0x1 40 #define IOSS_TELEM_INFO_READ 0x2 41 #define IOSS_TELEM_TRACE_CTL_READ 0x5 42 #define IOSS_TELEM_TRACE_CTL_WRITE 0x6 43 #define IOSS_TELEM_EVENT_CTL_READ 0x7 44 #define IOSS_TELEM_EVENT_CTL_WRITE 0x8 45 #define IOSS_TELEM_EVT_WRITE_SIZE 0x3 46 47 #define TELEM_INFO_SRAMEVTS_MASK 0xFF00 48 #define TELEM_INFO_SRAMEVTS_SHIFT 0x8 49 #define TELEM_SSRAM_READ_TIMEOUT 10 50 51 #define TELEM_INFO_NENABLES_MASK 0xFF 52 #define TELEM_EVENT_ENABLE 0x8000 53 54 #define TELEM_MASK_BIT 1 55 #define TELEM_MASK_BYTE 0xFF 56 #define BYTES_PER_LONG 8 57 #define TELEM_MASK_PCS_STATE 0xF 58 59 #define TELEM_DISABLE(x) ((x) &= ~(BIT(31))) 60 #define TELEM_CLEAR_EVENTS(x) ((x) |= (BIT(30))) 61 #define TELEM_ENABLE_SRAM_EVT_TRACE(x) ((x) &= ~(BIT(30) | BIT(24))) 62 #define TELEM_ENABLE_PERIODIC(x) ((x) |= (BIT(23) | BIT(31) | BIT(7))) 63 #define TELEM_EXTRACT_VERBOSITY(x, y) ((y) = (((x) >> 27) & 0x3)) 64 #define TELEM_CLEAR_VERBOSITY_BITS(x) ((x) &= ~(BIT(27) | BIT(28))) 65 #define TELEM_SET_VERBOSITY_BITS(x, y) ((x) |= ((y) << 27)) 66 67 enum telemetry_action { 68 TELEM_UPDATE = 0, 69 TELEM_ADD, 70 TELEM_RESET, 71 TELEM_ACTION_NONE 72 }; 73 74 struct telem_ssram_region { 75 u64 timestamp; 76 u64 start_time; 77 u64 events[TELEM_MAX_EVENTS_SRAM]; 78 }; 79 80 static struct telemetry_plt_config *telm_conf; 81 82 /* 83 * The following counters are programmed by default during setup. 84 * Only 20 allocated to kernel driver 85 */ 86 static struct telemetry_evtmap 87 telemetry_apl_ioss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = { 88 {"SOC_S0IX_TOTAL_RES", 0x4800}, 89 {"SOC_S0IX_TOTAL_OCC", 0x4000}, 90 {"SOC_S0IX_SHALLOW_RES", 0x4801}, 91 {"SOC_S0IX_SHALLOW_OCC", 0x4001}, 92 {"SOC_S0IX_DEEP_RES", 0x4802}, 93 {"SOC_S0IX_DEEP_OCC", 0x4002}, 94 {"PMC_POWER_GATE", 0x5818}, 95 {"PMC_D3_STATES", 0x5819}, 96 {"PMC_D0I3_STATES", 0x581A}, 97 {"PMC_S0IX_WAKE_REASON_GPIO", 0x6000}, 98 {"PMC_S0IX_WAKE_REASON_TIMER", 0x6001}, 99 {"PMC_S0IX_WAKE_REASON_VNNREQ", 0x6002}, 100 {"PMC_S0IX_WAKE_REASON_LOWPOWER", 0x6003}, 101 {"PMC_S0IX_WAKE_REASON_EXTERNAL", 0x6004}, 102 {"PMC_S0IX_WAKE_REASON_MISC", 0x6005}, 103 {"PMC_S0IX_BLOCKING_IPS_D3_D0I3", 0x6006}, 104 {"PMC_S0IX_BLOCKING_IPS_PG", 0x6007}, 105 {"PMC_S0IX_BLOCKING_MISC_IPS_PG", 0x6008}, 106 {"PMC_S0IX_BLOCK_IPS_VNN_REQ", 0x6009}, 107 {"PMC_S0IX_BLOCK_IPS_CLOCKS", 0x600B}, 108 }; 109 110 111 static struct telemetry_evtmap 112 telemetry_apl_pss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = { 113 {"IA_CORE0_C6_RES", 0x0400}, 114 {"IA_CORE0_C6_CTR", 0x0000}, 115 {"IA_MODULE0_C7_RES", 0x0410}, 116 {"IA_MODULE0_C7_CTR", 0x000E}, 117 {"IA_C0_RES", 0x0805}, 118 {"PCS_LTR", 0x2801}, 119 {"PSTATES", 0x2802}, 120 {"SOC_S0I3_RES", 0x0409}, 121 {"SOC_S0I3_CTR", 0x000A}, 122 {"PCS_S0I3_CTR", 0x0009}, 123 {"PCS_C1E_RES", 0x041A}, 124 {"PCS_IDLE_STATUS", 0x2806}, 125 {"IA_PERF_LIMITS", 0x280B}, 126 {"GT_PERF_LIMITS", 0x280C}, 127 {"PCS_WAKEUP_S0IX_CTR", 0x0030}, 128 {"PCS_IDLE_BLOCKED", 0x2C00}, 129 {"PCS_S0IX_BLOCKED", 0x2C01}, 130 {"PCS_S0IX_WAKE_REASONS", 0x2C02}, 131 {"PCS_LTR_BLOCKING", 0x2C03}, 132 {"PC2_AND_MEM_SHALLOW_IDLE_RES", 0x1D40}, 133 }; 134 135 static struct telemetry_evtmap 136 telemetry_glk_pss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = { 137 {"IA_CORE0_C6_RES", 0x0400}, 138 {"IA_CORE0_C6_CTR", 0x0000}, 139 {"IA_MODULE0_C7_RES", 0x0410}, 140 {"IA_MODULE0_C7_CTR", 0x000C}, 141 {"IA_C0_RES", 0x0805}, 142 {"PCS_LTR", 0x2801}, 143 {"PSTATES", 0x2802}, 144 {"SOC_S0I3_RES", 0x0407}, 145 {"SOC_S0I3_CTR", 0x0008}, 146 {"PCS_S0I3_CTR", 0x0007}, 147 {"PCS_C1E_RES", 0x0414}, 148 {"PCS_IDLE_STATUS", 0x2806}, 149 {"IA_PERF_LIMITS", 0x280B}, 150 {"GT_PERF_LIMITS", 0x280C}, 151 {"PCS_WAKEUP_S0IX_CTR", 0x0025}, 152 {"PCS_IDLE_BLOCKED", 0x2C00}, 153 {"PCS_S0IX_BLOCKED", 0x2C01}, 154 {"PCS_S0IX_WAKE_REASONS", 0x2C02}, 155 {"PCS_LTR_BLOCKING", 0x2C03}, 156 {"PC2_AND_MEM_SHALLOW_IDLE_RES", 0x1D40}, 157 }; 158 159 /* APL specific Data */ 160 static struct telemetry_plt_config telem_apl_config = { 161 .pss_config = { 162 .telem_evts = telemetry_apl_pss_default_events, 163 }, 164 .ioss_config = { 165 .telem_evts = telemetry_apl_ioss_default_events, 166 }, 167 }; 168 169 /* GLK specific Data */ 170 static struct telemetry_plt_config telem_glk_config = { 171 .pss_config = { 172 .telem_evts = telemetry_glk_pss_default_events, 173 }, 174 .ioss_config = { 175 .telem_evts = telemetry_apl_ioss_default_events, 176 }, 177 }; 178 179 static const struct x86_cpu_id telemetry_cpu_ids[] = { 180 X86_MATCH_VFM(INTEL_ATOM_GOLDMONT, &telem_apl_config), 181 X86_MATCH_VFM(INTEL_ATOM_GOLDMONT_PLUS, &telem_glk_config), 182 {} 183 }; 184 185 MODULE_DEVICE_TABLE(x86cpu, telemetry_cpu_ids); 186 187 static inline int telem_get_unitconfig(enum telemetry_unit telem_unit, 188 struct telemetry_unit_config **unit_config) 189 { 190 if (telem_unit == TELEM_PSS) 191 *unit_config = &(telm_conf->pss_config); 192 else if (telem_unit == TELEM_IOSS) 193 *unit_config = &(telm_conf->ioss_config); 194 else 195 return -EINVAL; 196 197 return 0; 198 199 } 200 201 static int telemetry_check_evtid(enum telemetry_unit telem_unit, 202 u32 *evtmap, u8 len, 203 enum telemetry_action action) 204 { 205 struct telemetry_unit_config *unit_config; 206 int ret; 207 208 ret = telem_get_unitconfig(telem_unit, &unit_config); 209 if (ret < 0) 210 return ret; 211 212 switch (action) { 213 case TELEM_RESET: 214 if (len > TELEM_MAX_EVENTS_SRAM) 215 return -EINVAL; 216 217 break; 218 219 case TELEM_UPDATE: 220 if (len > TELEM_MAX_EVENTS_SRAM) 221 return -EINVAL; 222 223 if ((len > 0) && (evtmap == NULL)) 224 return -EINVAL; 225 226 break; 227 228 case TELEM_ADD: 229 if ((len + unit_config->ssram_evts_used) > 230 TELEM_MAX_EVENTS_SRAM) 231 return -EINVAL; 232 233 if ((len > 0) && (evtmap == NULL)) 234 return -EINVAL; 235 236 break; 237 238 default: 239 pr_err("Unknown Telemetry action specified %d\n", action); 240 return -EINVAL; 241 } 242 243 return 0; 244 } 245 246 247 static inline int telemetry_plt_config_ioss_event(u32 evt_id, int index) 248 { 249 u32 write_buf; 250 251 write_buf = evt_id | TELEM_EVENT_ENABLE; 252 write_buf <<= BITS_PER_BYTE; 253 write_buf |= index; 254 255 return intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM, 256 IOSS_TELEM_EVENT_WRITE, &write_buf, 257 IOSS_TELEM_EVT_WRITE_SIZE, NULL, 0); 258 } 259 260 static inline int telemetry_plt_config_pss_event(u32 evt_id, int index) 261 { 262 u32 write_buf; 263 int ret; 264 265 write_buf = evt_id | TELEM_EVENT_ENABLE; 266 ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT, 267 index, 0, &write_buf, NULL); 268 269 return ret; 270 } 271 272 static int telemetry_setup_iossevtconfig(struct telemetry_evtconfig evtconfig, 273 enum telemetry_action action) 274 { 275 struct intel_scu_ipc_dev *scu = telm_conf->scu; 276 u8 num_ioss_evts, ioss_period; 277 int ret, index, idx; 278 u32 *ioss_evtmap; 279 u32 telem_ctrl; 280 281 num_ioss_evts = evtconfig.num_evts; 282 ioss_period = evtconfig.period; 283 ioss_evtmap = evtconfig.evtmap; 284 285 /* Get telemetry EVENT CTL */ 286 ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM, 287 IOSS_TELEM_EVENT_CTL_READ, NULL, 0, 288 &telem_ctrl, sizeof(telem_ctrl)); 289 if (ret) { 290 pr_err("IOSS TELEM_CTRL Read Failed\n"); 291 return ret; 292 } 293 294 /* Disable Telemetry */ 295 TELEM_DISABLE(telem_ctrl); 296 297 ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM, 298 IOSS_TELEM_EVENT_CTL_WRITE, &telem_ctrl, 299 sizeof(telem_ctrl), NULL, 0); 300 if (ret) { 301 pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n"); 302 return ret; 303 } 304 305 306 /* Reset Everything */ 307 if (action == TELEM_RESET) { 308 /* Clear All Events */ 309 TELEM_CLEAR_EVENTS(telem_ctrl); 310 311 ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM, 312 IOSS_TELEM_EVENT_CTL_WRITE, 313 &telem_ctrl, sizeof(telem_ctrl), 314 NULL, 0); 315 if (ret) { 316 pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n"); 317 return ret; 318 } 319 telm_conf->ioss_config.ssram_evts_used = 0; 320 321 /* Configure Events */ 322 for (idx = 0; idx < num_ioss_evts; idx++) { 323 if (telemetry_plt_config_ioss_event( 324 telm_conf->ioss_config.telem_evts[idx].evt_id, 325 idx)) { 326 pr_err("IOSS TELEM_RESET Fail for data: %x\n", 327 telm_conf->ioss_config.telem_evts[idx].evt_id); 328 continue; 329 } 330 telm_conf->ioss_config.ssram_evts_used++; 331 } 332 } 333 334 /* Re-Configure Everything */ 335 if (action == TELEM_UPDATE) { 336 /* Clear All Events */ 337 TELEM_CLEAR_EVENTS(telem_ctrl); 338 339 ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM, 340 IOSS_TELEM_EVENT_CTL_WRITE, 341 &telem_ctrl, sizeof(telem_ctrl), 342 NULL, 0); 343 if (ret) { 344 pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n"); 345 return ret; 346 } 347 telm_conf->ioss_config.ssram_evts_used = 0; 348 349 /* Configure Events */ 350 for (index = 0; index < num_ioss_evts; index++) { 351 telm_conf->ioss_config.telem_evts[index].evt_id = 352 ioss_evtmap[index]; 353 354 if (telemetry_plt_config_ioss_event( 355 telm_conf->ioss_config.telem_evts[index].evt_id, 356 index)) { 357 pr_err("IOSS TELEM_UPDATE Fail for Evt%x\n", 358 ioss_evtmap[index]); 359 continue; 360 } 361 telm_conf->ioss_config.ssram_evts_used++; 362 } 363 } 364 365 /* Add some Events */ 366 if (action == TELEM_ADD) { 367 /* Configure Events */ 368 for (index = telm_conf->ioss_config.ssram_evts_used, idx = 0; 369 idx < num_ioss_evts; index++, idx++) { 370 telm_conf->ioss_config.telem_evts[index].evt_id = 371 ioss_evtmap[idx]; 372 373 if (telemetry_plt_config_ioss_event( 374 telm_conf->ioss_config.telem_evts[index].evt_id, 375 index)) { 376 pr_err("IOSS TELEM_ADD Fail for Event %x\n", 377 ioss_evtmap[idx]); 378 continue; 379 } 380 telm_conf->ioss_config.ssram_evts_used++; 381 } 382 } 383 384 /* Enable Periodic Telemetry Events and enable SRAM trace */ 385 TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl); 386 TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl); 387 TELEM_ENABLE_PERIODIC(telem_ctrl); 388 telem_ctrl |= ioss_period; 389 390 ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM, 391 IOSS_TELEM_EVENT_CTL_WRITE, 392 &telem_ctrl, sizeof(telem_ctrl), NULL, 0); 393 if (ret) { 394 pr_err("IOSS TELEM_CTRL Event Enable Write Failed\n"); 395 return ret; 396 } 397 398 telm_conf->ioss_config.curr_period = ioss_period; 399 400 return 0; 401 } 402 403 404 static int telemetry_setup_pssevtconfig(struct telemetry_evtconfig evtconfig, 405 enum telemetry_action action) 406 { 407 u8 num_pss_evts, pss_period; 408 int ret, index, idx; 409 u32 *pss_evtmap; 410 u32 telem_ctrl; 411 412 num_pss_evts = evtconfig.num_evts; 413 pss_period = evtconfig.period; 414 pss_evtmap = evtconfig.evtmap; 415 416 /* PSS Config */ 417 /* Get telemetry EVENT CTL */ 418 ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL, 419 0, 0, NULL, &telem_ctrl); 420 if (ret) { 421 pr_err("PSS TELEM_CTRL Read Failed\n"); 422 return ret; 423 } 424 425 /* Disable Telemetry */ 426 TELEM_DISABLE(telem_ctrl); 427 ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL, 428 0, 0, &telem_ctrl, NULL); 429 if (ret) { 430 pr_err("PSS TELEM_CTRL Event Disable Write Failed\n"); 431 return ret; 432 } 433 434 /* Reset Everything */ 435 if (action == TELEM_RESET) { 436 /* Clear All Events */ 437 TELEM_CLEAR_EVENTS(telem_ctrl); 438 439 ret = intel_punit_ipc_command( 440 IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL, 441 0, 0, &telem_ctrl, NULL); 442 if (ret) { 443 pr_err("PSS TELEM_CTRL Event Disable Write Failed\n"); 444 return ret; 445 } 446 telm_conf->pss_config.ssram_evts_used = 0; 447 /* Configure Events */ 448 for (idx = 0; idx < num_pss_evts; idx++) { 449 if (telemetry_plt_config_pss_event( 450 telm_conf->pss_config.telem_evts[idx].evt_id, 451 idx)) { 452 pr_err("PSS TELEM_RESET Fail for Event %x\n", 453 telm_conf->pss_config.telem_evts[idx].evt_id); 454 continue; 455 } 456 telm_conf->pss_config.ssram_evts_used++; 457 } 458 } 459 460 /* Re-Configure Everything */ 461 if (action == TELEM_UPDATE) { 462 /* Clear All Events */ 463 TELEM_CLEAR_EVENTS(telem_ctrl); 464 465 ret = intel_punit_ipc_command( 466 IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL, 467 0, 0, &telem_ctrl, NULL); 468 if (ret) { 469 pr_err("PSS TELEM_CTRL Event Disable Write Failed\n"); 470 return ret; 471 } 472 telm_conf->pss_config.ssram_evts_used = 0; 473 474 /* Configure Events */ 475 for (index = 0; index < num_pss_evts; index++) { 476 telm_conf->pss_config.telem_evts[index].evt_id = 477 pss_evtmap[index]; 478 479 if (telemetry_plt_config_pss_event( 480 telm_conf->pss_config.telem_evts[index].evt_id, 481 index)) { 482 pr_err("PSS TELEM_UPDATE Fail for Event %x\n", 483 pss_evtmap[index]); 484 continue; 485 } 486 telm_conf->pss_config.ssram_evts_used++; 487 } 488 } 489 490 /* Add some Events */ 491 if (action == TELEM_ADD) { 492 /* Configure Events */ 493 for (index = telm_conf->pss_config.ssram_evts_used, idx = 0; 494 idx < num_pss_evts; index++, idx++) { 495 496 telm_conf->pss_config.telem_evts[index].evt_id = 497 pss_evtmap[idx]; 498 499 if (telemetry_plt_config_pss_event( 500 telm_conf->pss_config.telem_evts[index].evt_id, 501 index)) { 502 pr_err("PSS TELEM_ADD Fail for Event %x\n", 503 pss_evtmap[idx]); 504 continue; 505 } 506 telm_conf->pss_config.ssram_evts_used++; 507 } 508 } 509 510 /* Enable Periodic Telemetry Events and enable SRAM trace */ 511 TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl); 512 TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl); 513 TELEM_ENABLE_PERIODIC(telem_ctrl); 514 telem_ctrl |= pss_period; 515 516 ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL, 517 0, 0, &telem_ctrl, NULL); 518 if (ret) { 519 pr_err("PSS TELEM_CTRL Event Enable Write Failed\n"); 520 return ret; 521 } 522 523 telm_conf->pss_config.curr_period = pss_period; 524 525 return 0; 526 } 527 528 static int telemetry_setup_evtconfig(struct telemetry_evtconfig pss_evtconfig, 529 struct telemetry_evtconfig ioss_evtconfig, 530 enum telemetry_action action) 531 { 532 int ret; 533 534 mutex_lock(&(telm_conf->telem_lock)); 535 536 if ((action == TELEM_UPDATE) && (telm_conf->telem_in_use)) { 537 ret = -EBUSY; 538 goto out; 539 } 540 541 ret = telemetry_check_evtid(TELEM_PSS, pss_evtconfig.evtmap, 542 pss_evtconfig.num_evts, action); 543 if (ret) 544 goto out; 545 546 ret = telemetry_check_evtid(TELEM_IOSS, ioss_evtconfig.evtmap, 547 ioss_evtconfig.num_evts, action); 548 if (ret) 549 goto out; 550 551 if (ioss_evtconfig.num_evts) { 552 ret = telemetry_setup_iossevtconfig(ioss_evtconfig, action); 553 if (ret) 554 goto out; 555 } 556 557 if (pss_evtconfig.num_evts) { 558 ret = telemetry_setup_pssevtconfig(pss_evtconfig, action); 559 if (ret) 560 goto out; 561 } 562 563 if ((action == TELEM_UPDATE) || (action == TELEM_ADD)) 564 telm_conf->telem_in_use = true; 565 else 566 telm_conf->telem_in_use = false; 567 568 out: 569 mutex_unlock(&(telm_conf->telem_lock)); 570 return ret; 571 } 572 573 static int telemetry_setup(struct platform_device *pdev) 574 { 575 struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig; 576 u32 read_buf, events, event_regs; 577 int ret; 578 579 ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM, 580 IOSS_TELEM_INFO_READ, NULL, 0, 581 &read_buf, sizeof(read_buf)); 582 if (ret) { 583 dev_err(&pdev->dev, "IOSS TELEM_INFO Read Failed\n"); 584 return ret; 585 } 586 587 /* Get telemetry Info */ 588 events = (read_buf & TELEM_INFO_SRAMEVTS_MASK) >> 589 TELEM_INFO_SRAMEVTS_SHIFT; 590 event_regs = read_buf & TELEM_INFO_NENABLES_MASK; 591 if ((events < TELEM_MAX_EVENTS_SRAM) || 592 (event_regs < TELEM_MAX_EVENTS_SRAM)) { 593 dev_err(&pdev->dev, "IOSS:Insufficient Space for SRAM Trace\n"); 594 dev_err(&pdev->dev, "SRAM Events %d; Event Regs %d\n", 595 events, event_regs); 596 return -ENOMEM; 597 } 598 599 telm_conf->ioss_config.min_period = TELEM_MIN_PERIOD(read_buf); 600 telm_conf->ioss_config.max_period = TELEM_MAX_PERIOD(read_buf); 601 602 /* PUNIT Mailbox Setup */ 603 ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_READ_TELE_INFO, 0, 0, 604 NULL, &read_buf); 605 if (ret) { 606 dev_err(&pdev->dev, "PSS TELEM_INFO Read Failed\n"); 607 return ret; 608 } 609 610 /* Get telemetry Info */ 611 events = (read_buf & TELEM_INFO_SRAMEVTS_MASK) >> 612 TELEM_INFO_SRAMEVTS_SHIFT; 613 event_regs = read_buf & TELEM_INFO_SRAMEVTS_MASK; 614 if ((events < TELEM_MAX_EVENTS_SRAM) || 615 (event_regs < TELEM_MAX_EVENTS_SRAM)) { 616 dev_err(&pdev->dev, "PSS:Insufficient Space for SRAM Trace\n"); 617 dev_err(&pdev->dev, "SRAM Events %d; Event Regs %d\n", 618 events, event_regs); 619 return -ENOMEM; 620 } 621 622 telm_conf->pss_config.min_period = TELEM_MIN_PERIOD(read_buf); 623 telm_conf->pss_config.max_period = TELEM_MAX_PERIOD(read_buf); 624 625 pss_evtconfig.evtmap = NULL; 626 pss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS; 627 pss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD; 628 629 ioss_evtconfig.evtmap = NULL; 630 ioss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS; 631 ioss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD; 632 633 ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig, 634 TELEM_RESET); 635 if (ret) { 636 dev_err(&pdev->dev, "TELEMETRY Setup Failed\n"); 637 return ret; 638 } 639 return 0; 640 } 641 642 static int telem_evtlog_read(enum telemetry_unit telem_unit, 643 struct telem_ssram_region *ssram_region, u8 len) 644 { 645 struct telemetry_unit_config *unit_config; 646 u64 timestamp_prev, timestamp_next; 647 int ret, index, timeout = 0; 648 649 ret = telem_get_unitconfig(telem_unit, &unit_config); 650 if (ret < 0) 651 return ret; 652 653 if (len > unit_config->ssram_evts_used) 654 len = unit_config->ssram_evts_used; 655 656 do { 657 timestamp_prev = readq(unit_config->regmap); 658 if (!timestamp_prev) { 659 pr_err("Ssram under update. Please Try Later\n"); 660 return -EBUSY; 661 } 662 663 ssram_region->start_time = readq(unit_config->regmap + 664 TELEM_SSRAM_STARTTIME_OFFSET); 665 666 for (index = 0; index < len; index++) { 667 ssram_region->events[index] = 668 readq(unit_config->regmap + TELEM_SSRAM_EVTLOG_OFFSET + 669 BYTES_PER_LONG*index); 670 } 671 672 timestamp_next = readq(unit_config->regmap); 673 if (!timestamp_next) { 674 pr_err("Ssram under update. Please Try Later\n"); 675 return -EBUSY; 676 } 677 678 if (timeout++ > TELEM_SSRAM_READ_TIMEOUT) { 679 pr_err("Timeout while reading Events\n"); 680 return -EBUSY; 681 } 682 683 } while (timestamp_prev != timestamp_next); 684 685 ssram_region->timestamp = timestamp_next; 686 687 return len; 688 } 689 690 static int telemetry_plt_raw_read_eventlog(enum telemetry_unit telem_unit, 691 struct telemetry_evtlog *evtlog, 692 int len, int log_all_evts) 693 { 694 int index, idx1, ret, readlen = len; 695 struct telem_ssram_region ssram_region; 696 struct telemetry_evtmap *evtmap; 697 698 switch (telem_unit) { 699 case TELEM_PSS: 700 evtmap = telm_conf->pss_config.telem_evts; 701 break; 702 703 case TELEM_IOSS: 704 evtmap = telm_conf->ioss_config.telem_evts; 705 break; 706 707 default: 708 pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit); 709 return -EINVAL; 710 } 711 712 if (!log_all_evts) 713 readlen = TELEM_MAX_EVENTS_SRAM; 714 715 ret = telem_evtlog_read(telem_unit, &ssram_region, readlen); 716 if (ret < 0) 717 return ret; 718 719 /* Invalid evt-id array specified via length mismatch */ 720 if ((!log_all_evts) && (len > ret)) 721 return -EINVAL; 722 723 if (log_all_evts) 724 for (index = 0; index < ret; index++) { 725 evtlog[index].telem_evtlog = ssram_region.events[index]; 726 evtlog[index].telem_evtid = evtmap[index].evt_id; 727 } 728 else 729 for (index = 0, readlen = 0; (index < ret) && (readlen < len); 730 index++) { 731 for (idx1 = 0; idx1 < len; idx1++) { 732 /* Elements matched */ 733 if (evtmap[index].evt_id == 734 evtlog[idx1].telem_evtid) { 735 evtlog[idx1].telem_evtlog = 736 ssram_region.events[index]; 737 readlen++; 738 739 break; 740 } 741 } 742 } 743 744 return readlen; 745 } 746 747 static int telemetry_plt_read_eventlog(enum telemetry_unit telem_unit, 748 struct telemetry_evtlog *evtlog, int len, int log_all_evts) 749 { 750 int ret; 751 752 mutex_lock(&(telm_conf->telem_lock)); 753 ret = telemetry_plt_raw_read_eventlog(telem_unit, evtlog, 754 len, log_all_evts); 755 mutex_unlock(&(telm_conf->telem_lock)); 756 757 return ret; 758 } 759 760 static int telemetry_plt_get_trace_verbosity(enum telemetry_unit telem_unit, 761 u32 *verbosity) 762 { 763 u32 temp = 0; 764 int ret; 765 766 if (verbosity == NULL) 767 return -EINVAL; 768 769 mutex_lock(&(telm_conf->telem_trace_lock)); 770 switch (telem_unit) { 771 case TELEM_PSS: 772 ret = intel_punit_ipc_command( 773 IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL, 774 0, 0, NULL, &temp); 775 if (ret) { 776 pr_err("PSS TRACE_CTRL Read Failed\n"); 777 goto out; 778 } 779 780 break; 781 782 case TELEM_IOSS: 783 ret = intel_scu_ipc_dev_command(telm_conf->scu, 784 IOSS_TELEM, IOSS_TELEM_TRACE_CTL_READ, 785 NULL, 0, &temp, sizeof(temp)); 786 if (ret) { 787 pr_err("IOSS TRACE_CTL Read Failed\n"); 788 goto out; 789 } 790 791 break; 792 793 default: 794 pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit); 795 ret = -EINVAL; 796 break; 797 } 798 TELEM_EXTRACT_VERBOSITY(temp, *verbosity); 799 800 out: 801 mutex_unlock(&(telm_conf->telem_trace_lock)); 802 return ret; 803 } 804 805 static int telemetry_plt_set_trace_verbosity(enum telemetry_unit telem_unit, 806 u32 verbosity) 807 { 808 u32 temp = 0; 809 int ret; 810 811 verbosity &= TELEM_TRC_VERBOSITY_MASK; 812 813 mutex_lock(&(telm_conf->telem_trace_lock)); 814 switch (telem_unit) { 815 case TELEM_PSS: 816 ret = intel_punit_ipc_command( 817 IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL, 818 0, 0, NULL, &temp); 819 if (ret) { 820 pr_err("PSS TRACE_CTRL Read Failed\n"); 821 goto out; 822 } 823 824 TELEM_CLEAR_VERBOSITY_BITS(temp); 825 TELEM_SET_VERBOSITY_BITS(temp, verbosity); 826 827 ret = intel_punit_ipc_command( 828 IPC_PUNIT_BIOS_WRITE_TELE_TRACE_CTRL, 829 0, 0, &temp, NULL); 830 if (ret) { 831 pr_err("PSS TRACE_CTRL Verbosity Set Failed\n"); 832 goto out; 833 } 834 break; 835 836 case TELEM_IOSS: 837 ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM, 838 IOSS_TELEM_TRACE_CTL_READ, 839 NULL, 0, &temp, sizeof(temp)); 840 if (ret) { 841 pr_err("IOSS TRACE_CTL Read Failed\n"); 842 goto out; 843 } 844 845 TELEM_CLEAR_VERBOSITY_BITS(temp); 846 TELEM_SET_VERBOSITY_BITS(temp, verbosity); 847 848 ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM, 849 IOSS_TELEM_TRACE_CTL_WRITE, 850 &temp, sizeof(temp), NULL, 0); 851 if (ret) { 852 pr_err("IOSS TRACE_CTL Verbosity Set Failed\n"); 853 goto out; 854 } 855 break; 856 857 default: 858 pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit); 859 ret = -EINVAL; 860 break; 861 } 862 863 out: 864 mutex_unlock(&(telm_conf->telem_trace_lock)); 865 return ret; 866 } 867 868 static const struct telemetry_core_ops telm_pltops = { 869 .get_trace_verbosity = telemetry_plt_get_trace_verbosity, 870 .set_trace_verbosity = telemetry_plt_set_trace_verbosity, 871 .raw_read_eventlog = telemetry_plt_raw_read_eventlog, 872 .read_eventlog = telemetry_plt_read_eventlog, 873 }; 874 875 static int telemetry_pltdrv_probe(struct platform_device *pdev) 876 { 877 const struct x86_cpu_id *id; 878 void __iomem *mem; 879 int ret; 880 881 id = x86_match_cpu(telemetry_cpu_ids); 882 if (!id) 883 return -ENODEV; 884 885 telm_conf = (struct telemetry_plt_config *)id->driver_data; 886 887 telm_conf->pmc = dev_get_drvdata(pdev->dev.parent); 888 889 mem = devm_platform_ioremap_resource(pdev, 0); 890 if (IS_ERR(mem)) 891 return PTR_ERR(mem); 892 893 telm_conf->pss_config.regmap = mem; 894 895 mem = devm_platform_ioremap_resource(pdev, 1); 896 if (IS_ERR(mem)) 897 return PTR_ERR(mem); 898 899 telm_conf->ioss_config.regmap = mem; 900 901 telm_conf->scu = devm_intel_scu_ipc_dev_get(&pdev->dev); 902 if (!telm_conf->scu) { 903 ret = -EPROBE_DEFER; 904 goto out; 905 } 906 907 mutex_init(&telm_conf->telem_lock); 908 mutex_init(&telm_conf->telem_trace_lock); 909 910 ret = telemetry_setup(pdev); 911 if (ret) 912 goto out; 913 914 ret = telemetry_set_pltdata(&telm_pltops, telm_conf); 915 if (ret) { 916 dev_err(&pdev->dev, "TELEMETRY Set Pltops Failed.\n"); 917 goto out; 918 } 919 920 return 0; 921 922 out: 923 dev_err(&pdev->dev, "TELEMETRY Setup Failed.\n"); 924 925 return ret; 926 } 927 928 static void telemetry_pltdrv_remove(struct platform_device *pdev) 929 { 930 telemetry_clear_pltdata(); 931 } 932 933 static struct platform_driver telemetry_soc_driver = { 934 .probe = telemetry_pltdrv_probe, 935 .remove = telemetry_pltdrv_remove, 936 .driver = { 937 .name = DRIVER_NAME, 938 }, 939 }; 940 941 static int __init telemetry_module_init(void) 942 { 943 return platform_driver_register(&telemetry_soc_driver); 944 } 945 946 static void __exit telemetry_module_exit(void) 947 { 948 platform_driver_unregister(&telemetry_soc_driver); 949 } 950 951 device_initcall(telemetry_module_init); 952 module_exit(telemetry_module_exit); 953 954 MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>"); 955 MODULE_DESCRIPTION("Intel SoC Telemetry Platform Driver"); 956 MODULE_VERSION(DRIVER_VERSION); 957 MODULE_LICENSE("GPL v2"); 958