root/drivers/platform/x86/intel_telemetry_pltdrv.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. telem_get_unitconfig
  2. telemetry_check_evtid
  3. telemetry_plt_config_ioss_event
  4. telemetry_plt_config_pss_event
  5. telemetry_setup_iossevtconfig
  6. telemetry_setup_pssevtconfig
  7. telemetry_setup_evtconfig
  8. telemetry_setup
  9. telemetry_plt_update_events
  10. telemetry_plt_set_sampling_period
  11. telemetry_plt_get_sampling_period
  12. telemetry_plt_reset_events
  13. telemetry_plt_get_eventconfig
  14. telemetry_plt_add_events
  15. telem_evtlog_read
  16. telemetry_plt_raw_read_eventlog
  17. telemetry_plt_read_eventlog
  18. telemetry_plt_get_trace_verbosity
  19. telemetry_plt_set_trace_verbosity
  20. telemetry_pltdrv_probe
  21. telemetry_pltdrv_remove
  22. telemetry_module_init
  23. telemetry_module_exit

   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_pmc_ipc.h>
  19 #include <asm/intel_punit_ipc.h>
  20 #include <asm/intel_telemetry.h>
  21 
  22 #define DRIVER_NAME     "intel_telemetry"
  23 #define DRIVER_VERSION  "1.0.0"
  24 
  25 #define TELEM_TRC_VERBOSITY_MASK        0x3
  26 
  27 #define TELEM_MIN_PERIOD(x)             ((x) & 0x7F0000)
  28 #define TELEM_MAX_PERIOD(x)             ((x) & 0x7F000000)
  29 #define TELEM_SAMPLE_PERIOD_INVALID(x)  ((x) & (BIT(7)))
  30 #define TELEM_CLEAR_SAMPLE_PERIOD(x)    ((x) &= ~0x7F)
  31 
  32 #define TELEM_SAMPLING_DEFAULT_PERIOD   0xD
  33 
  34 #define TELEM_MAX_EVENTS_SRAM           28
  35 #define TELEM_SSRAM_STARTTIME_OFFSET    8
  36 #define TELEM_SSRAM_EVTLOG_OFFSET       16
  37 
  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_CTRL_WRITE_SIZE  0x4
  46 #define IOSS_TELEM_READ_WORD            0x1
  47 #define IOSS_TELEM_WRITE_FOURBYTES      0x4
  48 #define IOSS_TELEM_EVT_WRITE_SIZE       0x3
  49 
  50 #define TELEM_INFO_SRAMEVTS_MASK        0xFF00
  51 #define TELEM_INFO_SRAMEVTS_SHIFT       0x8
  52 #define TELEM_SSRAM_READ_TIMEOUT        10
  53 
  54 #define TELEM_INFO_NENABLES_MASK        0xFF
  55 #define TELEM_EVENT_ENABLE              0x8000
  56 
  57 #define TELEM_MASK_BIT                  1
  58 #define TELEM_MASK_BYTE                 0xFF
  59 #define BYTES_PER_LONG                  8
  60 #define TELEM_MASK_PCS_STATE            0xF
  61 
  62 #define TELEM_DISABLE(x)                ((x) &= ~(BIT(31)))
  63 #define TELEM_CLEAR_EVENTS(x)           ((x) |= (BIT(30)))
  64 #define TELEM_ENABLE_SRAM_EVT_TRACE(x)  ((x) &= ~(BIT(30) | BIT(24)))
  65 #define TELEM_ENABLE_PERIODIC(x)        ((x) |= (BIT(23) | BIT(31) | BIT(7)))
  66 #define TELEM_EXTRACT_VERBOSITY(x, y)   ((y) = (((x) >> 27) & 0x3))
  67 #define TELEM_CLEAR_VERBOSITY_BITS(x)   ((x) &= ~(BIT(27) | BIT(28)))
  68 #define TELEM_SET_VERBOSITY_BITS(x, y)  ((x) |= ((y) << 27))
  69 
  70 #define TELEM_CPU(model, data) \
  71         { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&data }
  72 
  73 enum telemetry_action {
  74         TELEM_UPDATE = 0,
  75         TELEM_ADD,
  76         TELEM_RESET,
  77         TELEM_ACTION_NONE
  78 };
  79 
  80 struct telem_ssram_region {
  81         u64 timestamp;
  82         u64 start_time;
  83         u64 events[TELEM_MAX_EVENTS_SRAM];
  84 };
  85 
  86 static struct telemetry_plt_config *telm_conf;
  87 
  88 /*
  89  * The following counters are programmed by default during setup.
  90  * Only 20 allocated to kernel driver
  91  */
  92 static struct telemetry_evtmap
  93         telemetry_apl_ioss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = {
  94         {"SOC_S0IX_TOTAL_RES",                  0x4800},
  95         {"SOC_S0IX_TOTAL_OCC",                  0x4000},
  96         {"SOC_S0IX_SHALLOW_RES",                0x4801},
  97         {"SOC_S0IX_SHALLOW_OCC",                0x4001},
  98         {"SOC_S0IX_DEEP_RES",                   0x4802},
  99         {"SOC_S0IX_DEEP_OCC",                   0x4002},
 100         {"PMC_POWER_GATE",                      0x5818},
 101         {"PMC_D3_STATES",                       0x5819},
 102         {"PMC_D0I3_STATES",                     0x581A},
 103         {"PMC_S0IX_WAKE_REASON_GPIO",           0x6000},
 104         {"PMC_S0IX_WAKE_REASON_TIMER",          0x6001},
 105         {"PMC_S0IX_WAKE_REASON_VNNREQ",         0x6002},
 106         {"PMC_S0IX_WAKE_REASON_LOWPOWER",       0x6003},
 107         {"PMC_S0IX_WAKE_REASON_EXTERNAL",       0x6004},
 108         {"PMC_S0IX_WAKE_REASON_MISC",           0x6005},
 109         {"PMC_S0IX_BLOCKING_IPS_D3_D0I3",       0x6006},
 110         {"PMC_S0IX_BLOCKING_IPS_PG",            0x6007},
 111         {"PMC_S0IX_BLOCKING_MISC_IPS_PG",       0x6008},
 112         {"PMC_S0IX_BLOCK_IPS_VNN_REQ",          0x6009},
 113         {"PMC_S0IX_BLOCK_IPS_CLOCKS",           0x600B},
 114 };
 115 
 116 
 117 static struct telemetry_evtmap
 118         telemetry_apl_pss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = {
 119         {"IA_CORE0_C6_RES",                     0x0400},
 120         {"IA_CORE0_C6_CTR",                     0x0000},
 121         {"IA_MODULE0_C7_RES",                   0x0410},
 122         {"IA_MODULE0_C7_CTR",                   0x000E},
 123         {"IA_C0_RES",                           0x0805},
 124         {"PCS_LTR",                             0x2801},
 125         {"PSTATES",                             0x2802},
 126         {"SOC_S0I3_RES",                        0x0409},
 127         {"SOC_S0I3_CTR",                        0x000A},
 128         {"PCS_S0I3_CTR",                        0x0009},
 129         {"PCS_C1E_RES",                         0x041A},
 130         {"PCS_IDLE_STATUS",                     0x2806},
 131         {"IA_PERF_LIMITS",                      0x280B},
 132         {"GT_PERF_LIMITS",                      0x280C},
 133         {"PCS_WAKEUP_S0IX_CTR",                 0x0030},
 134         {"PCS_IDLE_BLOCKED",                    0x2C00},
 135         {"PCS_S0IX_BLOCKED",                    0x2C01},
 136         {"PCS_S0IX_WAKE_REASONS",               0x2C02},
 137         {"PCS_LTR_BLOCKING",                    0x2C03},
 138         {"PC2_AND_MEM_SHALLOW_IDLE_RES",        0x1D40},
 139 };
 140 
 141 static struct telemetry_evtmap
 142         telemetry_glk_pss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = {
 143         {"IA_CORE0_C6_RES",                     0x0400},
 144         {"IA_CORE0_C6_CTR",                     0x0000},
 145         {"IA_MODULE0_C7_RES",                   0x0410},
 146         {"IA_MODULE0_C7_CTR",                   0x000C},
 147         {"IA_C0_RES",                           0x0805},
 148         {"PCS_LTR",                             0x2801},
 149         {"PSTATES",                             0x2802},
 150         {"SOC_S0I3_RES",                        0x0407},
 151         {"SOC_S0I3_CTR",                        0x0008},
 152         {"PCS_S0I3_CTR",                        0x0007},
 153         {"PCS_C1E_RES",                         0x0414},
 154         {"PCS_IDLE_STATUS",                     0x2806},
 155         {"IA_PERF_LIMITS",                      0x280B},
 156         {"GT_PERF_LIMITS",                      0x280C},
 157         {"PCS_WAKEUP_S0IX_CTR",                 0x0025},
 158         {"PCS_IDLE_BLOCKED",                    0x2C00},
 159         {"PCS_S0IX_BLOCKED",                    0x2C01},
 160         {"PCS_S0IX_WAKE_REASONS",               0x2C02},
 161         {"PCS_LTR_BLOCKING",                    0x2C03},
 162         {"PC2_AND_MEM_SHALLOW_IDLE_RES",        0x1D40},
 163 };
 164 
 165 /* APL specific Data */
 166 static struct telemetry_plt_config telem_apl_config = {
 167         .pss_config = {
 168                 .telem_evts = telemetry_apl_pss_default_events,
 169         },
 170         .ioss_config = {
 171                 .telem_evts = telemetry_apl_ioss_default_events,
 172         },
 173 };
 174 
 175 /* GLK specific Data */
 176 static struct telemetry_plt_config telem_glk_config = {
 177         .pss_config = {
 178                 .telem_evts = telemetry_glk_pss_default_events,
 179         },
 180         .ioss_config = {
 181                 .telem_evts = telemetry_apl_ioss_default_events,
 182         },
 183 };
 184 
 185 static const struct x86_cpu_id telemetry_cpu_ids[] = {
 186         TELEM_CPU(INTEL_FAM6_ATOM_GOLDMONT, telem_apl_config),
 187         TELEM_CPU(INTEL_FAM6_ATOM_GOLDMONT_PLUS, telem_glk_config),
 188         {}
 189 };
 190 
 191 MODULE_DEVICE_TABLE(x86cpu, telemetry_cpu_ids);
 192 
 193 static inline int telem_get_unitconfig(enum telemetry_unit telem_unit,
 194                                      struct telemetry_unit_config **unit_config)
 195 {
 196         if (telem_unit == TELEM_PSS)
 197                 *unit_config = &(telm_conf->pss_config);
 198         else if (telem_unit == TELEM_IOSS)
 199                 *unit_config = &(telm_conf->ioss_config);
 200         else
 201                 return -EINVAL;
 202 
 203         return 0;
 204 
 205 }
 206 
 207 static int telemetry_check_evtid(enum telemetry_unit telem_unit,
 208                                  u32 *evtmap, u8 len,
 209                                  enum telemetry_action action)
 210 {
 211         struct telemetry_unit_config *unit_config;
 212         int ret;
 213 
 214         ret = telem_get_unitconfig(telem_unit, &unit_config);
 215         if (ret < 0)
 216                 return ret;
 217 
 218         switch (action) {
 219         case TELEM_RESET:
 220                 if (len > TELEM_MAX_EVENTS_SRAM)
 221                         return -EINVAL;
 222 
 223                 break;
 224 
 225         case TELEM_UPDATE:
 226                 if (len > TELEM_MAX_EVENTS_SRAM)
 227                         return -EINVAL;
 228 
 229                 if ((len > 0) && (evtmap == NULL))
 230                         return -EINVAL;
 231 
 232                 break;
 233 
 234         case TELEM_ADD:
 235                 if ((len + unit_config->ssram_evts_used) >
 236                     TELEM_MAX_EVENTS_SRAM)
 237                         return -EINVAL;
 238 
 239                 if ((len > 0) && (evtmap == NULL))
 240                         return -EINVAL;
 241 
 242                 break;
 243 
 244         default:
 245                 pr_err("Unknown Telemetry action specified %d\n", action);
 246                 return -EINVAL;
 247         }
 248 
 249         return 0;
 250 }
 251 
 252 
 253 static inline int telemetry_plt_config_ioss_event(u32 evt_id, int index)
 254 {
 255         u32 write_buf;
 256         int ret;
 257 
 258         write_buf = evt_id | TELEM_EVENT_ENABLE;
 259         write_buf <<= BITS_PER_BYTE;
 260         write_buf |= index;
 261 
 262         ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
 263                                     IOSS_TELEM_EVENT_WRITE, (u8 *)&write_buf,
 264                                     IOSS_TELEM_EVT_WRITE_SIZE, NULL, 0);
 265 
 266         return ret;
 267 }
 268 
 269 static inline int telemetry_plt_config_pss_event(u32 evt_id, int index)
 270 {
 271         u32 write_buf;
 272         int ret;
 273 
 274         write_buf = evt_id | TELEM_EVENT_ENABLE;
 275         ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT,
 276                                       index, 0, &write_buf, NULL);
 277 
 278         return ret;
 279 }
 280 
 281 static int telemetry_setup_iossevtconfig(struct telemetry_evtconfig evtconfig,
 282                                          enum telemetry_action action)
 283 {
 284         u8 num_ioss_evts, ioss_period;
 285         int ret, index, idx;
 286         u32 *ioss_evtmap;
 287         u32 telem_ctrl;
 288 
 289         num_ioss_evts = evtconfig.num_evts;
 290         ioss_period = evtconfig.period;
 291         ioss_evtmap = evtconfig.evtmap;
 292 
 293         /* Get telemetry EVENT CTL */
 294         ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
 295                                     IOSS_TELEM_EVENT_CTL_READ, NULL, 0,
 296                                     &telem_ctrl, IOSS_TELEM_READ_WORD);
 297         if (ret) {
 298                 pr_err("IOSS TELEM_CTRL Read Failed\n");
 299                 return ret;
 300         }
 301 
 302         /* Disable Telemetry */
 303         TELEM_DISABLE(telem_ctrl);
 304 
 305         ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
 306                                     IOSS_TELEM_EVENT_CTL_WRITE,
 307                                     (u8 *)&telem_ctrl,
 308                                     IOSS_TELEM_EVT_CTRL_WRITE_SIZE,
 309                                     NULL, 0);
 310         if (ret) {
 311                 pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
 312                 return ret;
 313         }
 314 
 315 
 316         /* Reset Everything */
 317         if (action == TELEM_RESET) {
 318                 /* Clear All Events */
 319                 TELEM_CLEAR_EVENTS(telem_ctrl);
 320 
 321                 ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
 322                                             IOSS_TELEM_EVENT_CTL_WRITE,
 323                                             (u8 *)&telem_ctrl,
 324                                             IOSS_TELEM_EVT_CTRL_WRITE_SIZE,
 325                                             NULL, 0);
 326                 if (ret) {
 327                         pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
 328                         return ret;
 329                 }
 330                 telm_conf->ioss_config.ssram_evts_used = 0;
 331 
 332                 /* Configure Events */
 333                 for (idx = 0; idx < num_ioss_evts; idx++) {
 334                         if (telemetry_plt_config_ioss_event(
 335                             telm_conf->ioss_config.telem_evts[idx].evt_id,
 336                             idx)) {
 337                                 pr_err("IOSS TELEM_RESET Fail for data: %x\n",
 338                                 telm_conf->ioss_config.telem_evts[idx].evt_id);
 339                                 continue;
 340                         }
 341                         telm_conf->ioss_config.ssram_evts_used++;
 342                 }
 343         }
 344 
 345         /* Re-Configure Everything */
 346         if (action == TELEM_UPDATE) {
 347                 /* Clear All Events */
 348                 TELEM_CLEAR_EVENTS(telem_ctrl);
 349 
 350                 ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
 351                                             IOSS_TELEM_EVENT_CTL_WRITE,
 352                                             (u8 *)&telem_ctrl,
 353                                             IOSS_TELEM_EVT_CTRL_WRITE_SIZE,
 354                                             NULL, 0);
 355                 if (ret) {
 356                         pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
 357                         return ret;
 358                 }
 359                 telm_conf->ioss_config.ssram_evts_used = 0;
 360 
 361                 /* Configure Events */
 362                 for (index = 0; index < num_ioss_evts; index++) {
 363                         telm_conf->ioss_config.telem_evts[index].evt_id =
 364                         ioss_evtmap[index];
 365 
 366                         if (telemetry_plt_config_ioss_event(
 367                             telm_conf->ioss_config.telem_evts[index].evt_id,
 368                             index)) {
 369                                 pr_err("IOSS TELEM_UPDATE Fail for Evt%x\n",
 370                                         ioss_evtmap[index]);
 371                                 continue;
 372                         }
 373                         telm_conf->ioss_config.ssram_evts_used++;
 374                 }
 375         }
 376 
 377         /* Add some Events */
 378         if (action == TELEM_ADD) {
 379                 /* Configure Events */
 380                 for (index = telm_conf->ioss_config.ssram_evts_used, idx = 0;
 381                      idx < num_ioss_evts; index++, idx++) {
 382                         telm_conf->ioss_config.telem_evts[index].evt_id =
 383                         ioss_evtmap[idx];
 384 
 385                         if (telemetry_plt_config_ioss_event(
 386                             telm_conf->ioss_config.telem_evts[index].evt_id,
 387                             index)) {
 388                                 pr_err("IOSS TELEM_ADD Fail for Event %x\n",
 389                                         ioss_evtmap[idx]);
 390                                 continue;
 391                         }
 392                         telm_conf->ioss_config.ssram_evts_used++;
 393                 }
 394         }
 395 
 396         /* Enable Periodic Telemetry Events and enable SRAM trace */
 397         TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
 398         TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
 399         TELEM_ENABLE_PERIODIC(telem_ctrl);
 400         telem_ctrl |= ioss_period;
 401 
 402         ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
 403                                     IOSS_TELEM_EVENT_CTL_WRITE,
 404                                     (u8 *)&telem_ctrl,
 405                                     IOSS_TELEM_EVT_CTRL_WRITE_SIZE, NULL, 0);
 406         if (ret) {
 407                 pr_err("IOSS TELEM_CTRL Event Enable Write Failed\n");
 408                 return ret;
 409         }
 410 
 411         telm_conf->ioss_config.curr_period = ioss_period;
 412 
 413         return 0;
 414 }
 415 
 416 
 417 static int telemetry_setup_pssevtconfig(struct telemetry_evtconfig evtconfig,
 418                                         enum telemetry_action action)
 419 {
 420         u8 num_pss_evts, pss_period;
 421         int ret, index, idx;
 422         u32 *pss_evtmap;
 423         u32 telem_ctrl;
 424 
 425         num_pss_evts = evtconfig.num_evts;
 426         pss_period = evtconfig.period;
 427         pss_evtmap = evtconfig.evtmap;
 428 
 429         /* PSS Config */
 430         /* Get telemetry EVENT CTL */
 431         ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL,
 432                                       0, 0, NULL, &telem_ctrl);
 433         if (ret) {
 434                 pr_err("PSS TELEM_CTRL Read Failed\n");
 435                 return ret;
 436         }
 437 
 438         /* Disable Telemetry */
 439         TELEM_DISABLE(telem_ctrl);
 440         ret = intel_punit_ipc_command(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 
 447         /* Reset Everything */
 448         if (action == TELEM_RESET) {
 449                 /* Clear All Events */
 450                 TELEM_CLEAR_EVENTS(telem_ctrl);
 451 
 452                 ret = intel_punit_ipc_command(
 453                                 IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
 454                                 0, 0, &telem_ctrl, NULL);
 455                 if (ret) {
 456                         pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
 457                         return ret;
 458                 }
 459                 telm_conf->pss_config.ssram_evts_used = 0;
 460                 /* Configure Events */
 461                 for (idx = 0; idx < num_pss_evts; idx++) {
 462                         if (telemetry_plt_config_pss_event(
 463                             telm_conf->pss_config.telem_evts[idx].evt_id,
 464                             idx)) {
 465                                 pr_err("PSS TELEM_RESET Fail for Event %x\n",
 466                                 telm_conf->pss_config.telem_evts[idx].evt_id);
 467                                 continue;
 468                         }
 469                         telm_conf->pss_config.ssram_evts_used++;
 470                 }
 471         }
 472 
 473         /* Re-Configure Everything */
 474         if (action == TELEM_UPDATE) {
 475                 /* Clear All Events */
 476                 TELEM_CLEAR_EVENTS(telem_ctrl);
 477 
 478                 ret = intel_punit_ipc_command(
 479                                 IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
 480                                 0, 0, &telem_ctrl, NULL);
 481                 if (ret) {
 482                         pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
 483                         return ret;
 484                 }
 485                 telm_conf->pss_config.ssram_evts_used = 0;
 486 
 487                 /* Configure Events */
 488                 for (index = 0; index < num_pss_evts; index++) {
 489                         telm_conf->pss_config.telem_evts[index].evt_id =
 490                         pss_evtmap[index];
 491 
 492                         if (telemetry_plt_config_pss_event(
 493                             telm_conf->pss_config.telem_evts[index].evt_id,
 494                             index)) {
 495                                 pr_err("PSS TELEM_UPDATE Fail for Event %x\n",
 496                                         pss_evtmap[index]);
 497                                 continue;
 498                         }
 499                         telm_conf->pss_config.ssram_evts_used++;
 500                 }
 501         }
 502 
 503         /* Add some Events */
 504         if (action == TELEM_ADD) {
 505                 /* Configure Events */
 506                 for (index = telm_conf->pss_config.ssram_evts_used, idx = 0;
 507                      idx < num_pss_evts; index++, idx++) {
 508 
 509                         telm_conf->pss_config.telem_evts[index].evt_id =
 510                         pss_evtmap[idx];
 511 
 512                         if (telemetry_plt_config_pss_event(
 513                             telm_conf->pss_config.telem_evts[index].evt_id,
 514                             index)) {
 515                                 pr_err("PSS TELEM_ADD Fail for Event %x\n",
 516                                         pss_evtmap[idx]);
 517                                 continue;
 518                         }
 519                         telm_conf->pss_config.ssram_evts_used++;
 520                 }
 521         }
 522 
 523         /* Enable Periodic Telemetry Events and enable SRAM trace */
 524         TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
 525         TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
 526         TELEM_ENABLE_PERIODIC(telem_ctrl);
 527         telem_ctrl |= pss_period;
 528 
 529         ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
 530                                       0, 0, &telem_ctrl, NULL);
 531         if (ret) {
 532                 pr_err("PSS TELEM_CTRL Event Enable Write Failed\n");
 533                 return ret;
 534         }
 535 
 536         telm_conf->pss_config.curr_period = pss_period;
 537 
 538         return 0;
 539 }
 540 
 541 static int telemetry_setup_evtconfig(struct telemetry_evtconfig pss_evtconfig,
 542                                      struct telemetry_evtconfig ioss_evtconfig,
 543                                      enum telemetry_action action)
 544 {
 545         int ret;
 546 
 547         mutex_lock(&(telm_conf->telem_lock));
 548 
 549         if ((action == TELEM_UPDATE) && (telm_conf->telem_in_use)) {
 550                 ret = -EBUSY;
 551                 goto out;
 552         }
 553 
 554         ret = telemetry_check_evtid(TELEM_PSS, pss_evtconfig.evtmap,
 555                                     pss_evtconfig.num_evts, action);
 556         if (ret)
 557                 goto out;
 558 
 559         ret = telemetry_check_evtid(TELEM_IOSS, ioss_evtconfig.evtmap,
 560                                     ioss_evtconfig.num_evts, action);
 561         if (ret)
 562                 goto out;
 563 
 564         if (ioss_evtconfig.num_evts) {
 565                 ret = telemetry_setup_iossevtconfig(ioss_evtconfig, action);
 566                 if (ret)
 567                         goto out;
 568         }
 569 
 570         if (pss_evtconfig.num_evts) {
 571                 ret = telemetry_setup_pssevtconfig(pss_evtconfig, action);
 572                 if (ret)
 573                         goto out;
 574         }
 575 
 576         if ((action == TELEM_UPDATE) || (action == TELEM_ADD))
 577                 telm_conf->telem_in_use = true;
 578         else
 579                 telm_conf->telem_in_use = false;
 580 
 581 out:
 582         mutex_unlock(&(telm_conf->telem_lock));
 583         return ret;
 584 }
 585 
 586 static int telemetry_setup(struct platform_device *pdev)
 587 {
 588         struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig;
 589         u32 read_buf, events, event_regs;
 590         int ret;
 591 
 592         ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY, IOSS_TELEM_INFO_READ,
 593                                     NULL, 0, &read_buf, IOSS_TELEM_READ_WORD);
 594         if (ret) {
 595                 dev_err(&pdev->dev, "IOSS TELEM_INFO Read Failed\n");
 596                 return ret;
 597         }
 598 
 599         /* Get telemetry Info */
 600         events = (read_buf & TELEM_INFO_SRAMEVTS_MASK) >>
 601                   TELEM_INFO_SRAMEVTS_SHIFT;
 602         event_regs = read_buf & TELEM_INFO_NENABLES_MASK;
 603         if ((events < TELEM_MAX_EVENTS_SRAM) ||
 604             (event_regs < TELEM_MAX_EVENTS_SRAM)) {
 605                 dev_err(&pdev->dev, "IOSS:Insufficient Space for SRAM Trace\n");
 606                 dev_err(&pdev->dev, "SRAM Events %d; Event Regs %d\n",
 607                         events, event_regs);
 608                 return -ENOMEM;
 609         }
 610 
 611         telm_conf->ioss_config.min_period = TELEM_MIN_PERIOD(read_buf);
 612         telm_conf->ioss_config.max_period = TELEM_MAX_PERIOD(read_buf);
 613 
 614         /* PUNIT Mailbox Setup */
 615         ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_READ_TELE_INFO, 0, 0,
 616                                       NULL, &read_buf);
 617         if (ret) {
 618                 dev_err(&pdev->dev, "PSS TELEM_INFO Read Failed\n");
 619                 return ret;
 620         }
 621 
 622         /* Get telemetry Info */
 623         events = (read_buf & TELEM_INFO_SRAMEVTS_MASK) >>
 624                   TELEM_INFO_SRAMEVTS_SHIFT;
 625         event_regs = read_buf & TELEM_INFO_SRAMEVTS_MASK;
 626         if ((events < TELEM_MAX_EVENTS_SRAM) ||
 627             (event_regs < TELEM_MAX_EVENTS_SRAM)) {
 628                 dev_err(&pdev->dev, "PSS:Insufficient Space for SRAM Trace\n");
 629                 dev_err(&pdev->dev, "SRAM Events %d; Event Regs %d\n",
 630                         events, event_regs);
 631                 return -ENOMEM;
 632         }
 633 
 634         telm_conf->pss_config.min_period = TELEM_MIN_PERIOD(read_buf);
 635         telm_conf->pss_config.max_period = TELEM_MAX_PERIOD(read_buf);
 636 
 637         pss_evtconfig.evtmap = NULL;
 638         pss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
 639         pss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
 640 
 641         ioss_evtconfig.evtmap = NULL;
 642         ioss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
 643         ioss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
 644 
 645         ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
 646                                         TELEM_RESET);
 647         if (ret) {
 648                 dev_err(&pdev->dev, "TELEMETRY Setup Failed\n");
 649                 return ret;
 650         }
 651         return 0;
 652 }
 653 
 654 static int telemetry_plt_update_events(struct telemetry_evtconfig pss_evtconfig,
 655                                 struct telemetry_evtconfig ioss_evtconfig)
 656 {
 657         int ret;
 658 
 659         if ((pss_evtconfig.num_evts > 0) &&
 660             (TELEM_SAMPLE_PERIOD_INVALID(pss_evtconfig.period))) {
 661                 pr_err("PSS Sampling Period Out of Range\n");
 662                 return -EINVAL;
 663         }
 664 
 665         if ((ioss_evtconfig.num_evts > 0) &&
 666             (TELEM_SAMPLE_PERIOD_INVALID(ioss_evtconfig.period))) {
 667                 pr_err("IOSS Sampling Period Out of Range\n");
 668                 return -EINVAL;
 669         }
 670 
 671         ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
 672                                         TELEM_UPDATE);
 673         if (ret)
 674                 pr_err("TELEMETRY Config Failed\n");
 675 
 676         return ret;
 677 }
 678 
 679 
 680 static int telemetry_plt_set_sampling_period(u8 pss_period, u8 ioss_period)
 681 {
 682         u32 telem_ctrl = 0;
 683         int ret = 0;
 684 
 685         mutex_lock(&(telm_conf->telem_lock));
 686         if (ioss_period) {
 687                 if (TELEM_SAMPLE_PERIOD_INVALID(ioss_period)) {
 688                         pr_err("IOSS Sampling Period Out of Range\n");
 689                         ret = -EINVAL;
 690                         goto out;
 691                 }
 692 
 693                 /* Get telemetry EVENT CTL */
 694                 ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
 695                                             IOSS_TELEM_EVENT_CTL_READ, NULL, 0,
 696                                             &telem_ctrl, IOSS_TELEM_READ_WORD);
 697                 if (ret) {
 698                         pr_err("IOSS TELEM_CTRL Read Failed\n");
 699                         goto out;
 700                 }
 701 
 702                 /* Disable Telemetry */
 703                 TELEM_DISABLE(telem_ctrl);
 704 
 705                 ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
 706                                             IOSS_TELEM_EVENT_CTL_WRITE,
 707                                             (u8 *)&telem_ctrl,
 708                                             IOSS_TELEM_EVT_CTRL_WRITE_SIZE,
 709                                             NULL, 0);
 710                 if (ret) {
 711                         pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
 712                         goto out;
 713                 }
 714 
 715                 /* Enable Periodic Telemetry Events and enable SRAM trace */
 716                 TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
 717                 TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
 718                 TELEM_ENABLE_PERIODIC(telem_ctrl);
 719                 telem_ctrl |= ioss_period;
 720 
 721                 ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
 722                                             IOSS_TELEM_EVENT_CTL_WRITE,
 723                                             (u8 *)&telem_ctrl,
 724                                             IOSS_TELEM_EVT_CTRL_WRITE_SIZE,
 725                                             NULL, 0);
 726                 if (ret) {
 727                         pr_err("IOSS TELEM_CTRL Event Enable Write Failed\n");
 728                         goto out;
 729                 }
 730                 telm_conf->ioss_config.curr_period = ioss_period;
 731         }
 732 
 733         if (pss_period) {
 734                 if (TELEM_SAMPLE_PERIOD_INVALID(pss_period)) {
 735                         pr_err("PSS Sampling Period Out of Range\n");
 736                         ret = -EINVAL;
 737                         goto out;
 738                 }
 739 
 740                 /* Get telemetry EVENT CTL */
 741                 ret = intel_punit_ipc_command(
 742                                 IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL,
 743                                 0, 0, NULL, &telem_ctrl);
 744                 if (ret) {
 745                         pr_err("PSS TELEM_CTRL Read Failed\n");
 746                         goto out;
 747                 }
 748 
 749                 /* Disable Telemetry */
 750                 TELEM_DISABLE(telem_ctrl);
 751                 ret = intel_punit_ipc_command(
 752                                 IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
 753                                 0, 0, &telem_ctrl, NULL);
 754                 if (ret) {
 755                         pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
 756                         goto out;
 757                 }
 758 
 759                 /* Enable Periodic Telemetry Events and enable SRAM trace */
 760                 TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
 761                 TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
 762                 TELEM_ENABLE_PERIODIC(telem_ctrl);
 763                 telem_ctrl |= pss_period;
 764 
 765                 ret = intel_punit_ipc_command(
 766                                 IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
 767                                 0, 0, &telem_ctrl, NULL);
 768                 if (ret) {
 769                         pr_err("PSS TELEM_CTRL Event Enable Write Failed\n");
 770                         goto out;
 771                 }
 772                 telm_conf->pss_config.curr_period = pss_period;
 773         }
 774 
 775 out:
 776         mutex_unlock(&(telm_conf->telem_lock));
 777         return ret;
 778 }
 779 
 780 
 781 static int telemetry_plt_get_sampling_period(u8 *pss_min_period,
 782                                              u8 *pss_max_period,
 783                                              u8 *ioss_min_period,
 784                                              u8 *ioss_max_period)
 785 {
 786         *pss_min_period = telm_conf->pss_config.min_period;
 787         *pss_max_period = telm_conf->pss_config.max_period;
 788         *ioss_min_period = telm_conf->ioss_config.min_period;
 789         *ioss_max_period = telm_conf->ioss_config.max_period;
 790 
 791         return 0;
 792 }
 793 
 794 
 795 static int telemetry_plt_reset_events(void)
 796 {
 797         struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig;
 798         int ret;
 799 
 800         pss_evtconfig.evtmap = NULL;
 801         pss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
 802         pss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
 803 
 804         ioss_evtconfig.evtmap = NULL;
 805         ioss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
 806         ioss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
 807 
 808         ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
 809                                         TELEM_RESET);
 810         if (ret)
 811                 pr_err("TELEMETRY Reset Failed\n");
 812 
 813         return ret;
 814 }
 815 
 816 
 817 static int telemetry_plt_get_eventconfig(struct telemetry_evtconfig *pss_config,
 818                                         struct telemetry_evtconfig *ioss_config,
 819                                         int pss_len, int ioss_len)
 820 {
 821         u32 *pss_evtmap, *ioss_evtmap;
 822         u32 index;
 823 
 824         pss_evtmap = pss_config->evtmap;
 825         ioss_evtmap = ioss_config->evtmap;
 826 
 827         mutex_lock(&(telm_conf->telem_lock));
 828         pss_config->num_evts = telm_conf->pss_config.ssram_evts_used;
 829         ioss_config->num_evts = telm_conf->ioss_config.ssram_evts_used;
 830 
 831         pss_config->period = telm_conf->pss_config.curr_period;
 832         ioss_config->period = telm_conf->ioss_config.curr_period;
 833 
 834         if ((pss_len < telm_conf->pss_config.ssram_evts_used) ||
 835             (ioss_len < telm_conf->ioss_config.ssram_evts_used)) {
 836                 mutex_unlock(&(telm_conf->telem_lock));
 837                 return -EINVAL;
 838         }
 839 
 840         for (index = 0; index < telm_conf->pss_config.ssram_evts_used;
 841              index++) {
 842                 pss_evtmap[index] =
 843                 telm_conf->pss_config.telem_evts[index].evt_id;
 844         }
 845 
 846         for (index = 0; index < telm_conf->ioss_config.ssram_evts_used;
 847              index++) {
 848                 ioss_evtmap[index] =
 849                 telm_conf->ioss_config.telem_evts[index].evt_id;
 850         }
 851 
 852         mutex_unlock(&(telm_conf->telem_lock));
 853         return 0;
 854 }
 855 
 856 
 857 static int telemetry_plt_add_events(u8 num_pss_evts, u8 num_ioss_evts,
 858                                     u32 *pss_evtmap, u32 *ioss_evtmap)
 859 {
 860         struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig;
 861         int ret;
 862 
 863         pss_evtconfig.evtmap = pss_evtmap;
 864         pss_evtconfig.num_evts = num_pss_evts;
 865         pss_evtconfig.period = telm_conf->pss_config.curr_period;
 866 
 867         ioss_evtconfig.evtmap = ioss_evtmap;
 868         ioss_evtconfig.num_evts = num_ioss_evts;
 869         ioss_evtconfig.period = telm_conf->ioss_config.curr_period;
 870 
 871         ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
 872                                         TELEM_ADD);
 873         if (ret)
 874                 pr_err("TELEMETRY ADD Failed\n");
 875 
 876         return ret;
 877 }
 878 
 879 static int telem_evtlog_read(enum telemetry_unit telem_unit,
 880                              struct telem_ssram_region *ssram_region, u8 len)
 881 {
 882         struct telemetry_unit_config *unit_config;
 883         u64 timestamp_prev, timestamp_next;
 884         int ret, index, timeout = 0;
 885 
 886         ret = telem_get_unitconfig(telem_unit, &unit_config);
 887         if (ret < 0)
 888                 return ret;
 889 
 890         if (len > unit_config->ssram_evts_used)
 891                 len = unit_config->ssram_evts_used;
 892 
 893         do {
 894                 timestamp_prev = readq(unit_config->regmap);
 895                 if (!timestamp_prev) {
 896                         pr_err("Ssram under update. Please Try Later\n");
 897                         return -EBUSY;
 898                 }
 899 
 900                 ssram_region->start_time = readq(unit_config->regmap +
 901                                                  TELEM_SSRAM_STARTTIME_OFFSET);
 902 
 903                 for (index = 0; index < len; index++) {
 904                         ssram_region->events[index] =
 905                         readq(unit_config->regmap + TELEM_SSRAM_EVTLOG_OFFSET +
 906                               BYTES_PER_LONG*index);
 907                 }
 908 
 909                 timestamp_next = readq(unit_config->regmap);
 910                 if (!timestamp_next) {
 911                         pr_err("Ssram under update. Please Try Later\n");
 912                         return -EBUSY;
 913                 }
 914 
 915                 if (timeout++ > TELEM_SSRAM_READ_TIMEOUT) {
 916                         pr_err("Timeout while reading Events\n");
 917                         return -EBUSY;
 918                 }
 919 
 920         } while (timestamp_prev != timestamp_next);
 921 
 922         ssram_region->timestamp = timestamp_next;
 923 
 924         return len;
 925 }
 926 
 927 static int telemetry_plt_raw_read_eventlog(enum telemetry_unit telem_unit,
 928                                            struct telemetry_evtlog *evtlog,
 929                                            int len, int log_all_evts)
 930 {
 931         int index, idx1, ret, readlen = len;
 932         struct telem_ssram_region ssram_region;
 933         struct telemetry_evtmap *evtmap;
 934 
 935         switch (telem_unit)     {
 936         case TELEM_PSS:
 937                 evtmap = telm_conf->pss_config.telem_evts;
 938                 break;
 939 
 940         case TELEM_IOSS:
 941                 evtmap = telm_conf->ioss_config.telem_evts;
 942                 break;
 943 
 944         default:
 945                 pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit);
 946                 return -EINVAL;
 947         }
 948 
 949         if (!log_all_evts)
 950                 readlen = TELEM_MAX_EVENTS_SRAM;
 951 
 952         ret = telem_evtlog_read(telem_unit, &ssram_region, readlen);
 953         if (ret < 0)
 954                 return ret;
 955 
 956         /* Invalid evt-id array specified via length mismatch */
 957         if ((!log_all_evts) && (len > ret))
 958                 return -EINVAL;
 959 
 960         if (log_all_evts)
 961                 for (index = 0; index < ret; index++) {
 962                         evtlog[index].telem_evtlog = ssram_region.events[index];
 963                         evtlog[index].telem_evtid = evtmap[index].evt_id;
 964                 }
 965         else
 966                 for (index = 0, readlen = 0; (index < ret) && (readlen < len);
 967                      index++) {
 968                         for (idx1 = 0; idx1 < len; idx1++) {
 969                                 /* Elements matched */
 970                                 if (evtmap[index].evt_id ==
 971                                     evtlog[idx1].telem_evtid) {
 972                                         evtlog[idx1].telem_evtlog =
 973                                         ssram_region.events[index];
 974                                         readlen++;
 975 
 976                                         break;
 977                                 }
 978                         }
 979                 }
 980 
 981         return readlen;
 982 }
 983 
 984 static int telemetry_plt_read_eventlog(enum telemetry_unit telem_unit,
 985                 struct telemetry_evtlog *evtlog, int len, int log_all_evts)
 986 {
 987         int ret;
 988 
 989         mutex_lock(&(telm_conf->telem_lock));
 990         ret = telemetry_plt_raw_read_eventlog(telem_unit, evtlog,
 991                                               len, log_all_evts);
 992         mutex_unlock(&(telm_conf->telem_lock));
 993 
 994         return ret;
 995 }
 996 
 997 static int telemetry_plt_get_trace_verbosity(enum telemetry_unit telem_unit,
 998                                              u32 *verbosity)
 999 {
1000         u32 temp = 0;
1001         int ret;
1002 
1003         if (verbosity == NULL)
1004                 return -EINVAL;
1005 
1006         mutex_lock(&(telm_conf->telem_trace_lock));
1007         switch (telem_unit) {
1008         case TELEM_PSS:
1009                 ret = intel_punit_ipc_command(
1010                                 IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL,
1011                                 0, 0, NULL, &temp);
1012                 if (ret) {
1013                         pr_err("PSS TRACE_CTRL Read Failed\n");
1014                         goto out;
1015                 }
1016 
1017                 break;
1018 
1019         case TELEM_IOSS:
1020                 ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
1021                                 IOSS_TELEM_TRACE_CTL_READ, NULL, 0, &temp,
1022                                 IOSS_TELEM_READ_WORD);
1023                 if (ret) {
1024                         pr_err("IOSS TRACE_CTL Read Failed\n");
1025                         goto out;
1026                 }
1027 
1028                 break;
1029 
1030         default:
1031                 pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit);
1032                 ret = -EINVAL;
1033                 break;
1034         }
1035         TELEM_EXTRACT_VERBOSITY(temp, *verbosity);
1036 
1037 out:
1038         mutex_unlock(&(telm_conf->telem_trace_lock));
1039         return ret;
1040 }
1041 
1042 static int telemetry_plt_set_trace_verbosity(enum telemetry_unit telem_unit,
1043                                              u32 verbosity)
1044 {
1045         u32 temp = 0;
1046         int ret;
1047 
1048         verbosity &= TELEM_TRC_VERBOSITY_MASK;
1049 
1050         mutex_lock(&(telm_conf->telem_trace_lock));
1051         switch (telem_unit) {
1052         case TELEM_PSS:
1053                 ret = intel_punit_ipc_command(
1054                                 IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL,
1055                                 0, 0, NULL, &temp);
1056                 if (ret) {
1057                         pr_err("PSS TRACE_CTRL Read Failed\n");
1058                         goto out;
1059                 }
1060 
1061                 TELEM_CLEAR_VERBOSITY_BITS(temp);
1062                 TELEM_SET_VERBOSITY_BITS(temp, verbosity);
1063 
1064                 ret = intel_punit_ipc_command(
1065                                 IPC_PUNIT_BIOS_WRITE_TELE_TRACE_CTRL,
1066                                 0, 0, &temp, NULL);
1067                 if (ret) {
1068                         pr_err("PSS TRACE_CTRL Verbosity Set Failed\n");
1069                         goto out;
1070                 }
1071                 break;
1072 
1073         case TELEM_IOSS:
1074                 ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
1075                                 IOSS_TELEM_TRACE_CTL_READ, NULL, 0, &temp,
1076                                 IOSS_TELEM_READ_WORD);
1077                 if (ret) {
1078                         pr_err("IOSS TRACE_CTL Read Failed\n");
1079                         goto out;
1080                 }
1081 
1082                 TELEM_CLEAR_VERBOSITY_BITS(temp);
1083                 TELEM_SET_VERBOSITY_BITS(temp, verbosity);
1084 
1085                 ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
1086                                 IOSS_TELEM_TRACE_CTL_WRITE, (u8 *)&temp,
1087                                 IOSS_TELEM_WRITE_FOURBYTES, NULL, 0);
1088                 if (ret) {
1089                         pr_err("IOSS TRACE_CTL Verbosity Set Failed\n");
1090                         goto out;
1091                 }
1092                 break;
1093 
1094         default:
1095                 pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit);
1096                 ret = -EINVAL;
1097                 break;
1098         }
1099 
1100 out:
1101         mutex_unlock(&(telm_conf->telem_trace_lock));
1102         return ret;
1103 }
1104 
1105 static const struct telemetry_core_ops telm_pltops = {
1106         .get_trace_verbosity = telemetry_plt_get_trace_verbosity,
1107         .set_trace_verbosity = telemetry_plt_set_trace_verbosity,
1108         .set_sampling_period = telemetry_plt_set_sampling_period,
1109         .get_sampling_period = telemetry_plt_get_sampling_period,
1110         .raw_read_eventlog = telemetry_plt_raw_read_eventlog,
1111         .get_eventconfig = telemetry_plt_get_eventconfig,
1112         .update_events = telemetry_plt_update_events,
1113         .read_eventlog = telemetry_plt_read_eventlog,
1114         .reset_events = telemetry_plt_reset_events,
1115         .add_events = telemetry_plt_add_events,
1116 };
1117 
1118 static int telemetry_pltdrv_probe(struct platform_device *pdev)
1119 {
1120         struct resource *res0 = NULL, *res1 = NULL;
1121         const struct x86_cpu_id *id;
1122         int size, ret = -ENOMEM;
1123 
1124         id = x86_match_cpu(telemetry_cpu_ids);
1125         if (!id)
1126                 return -ENODEV;
1127 
1128         telm_conf = (struct telemetry_plt_config *)id->driver_data;
1129 
1130         res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1131         if (!res0) {
1132                 ret = -EINVAL;
1133                 goto out;
1134         }
1135         size = resource_size(res0);
1136         if (!devm_request_mem_region(&pdev->dev, res0->start, size,
1137                                      pdev->name)) {
1138                 ret = -EBUSY;
1139                 goto out;
1140         }
1141         telm_conf->pss_config.ssram_base_addr = res0->start;
1142         telm_conf->pss_config.ssram_size = size;
1143 
1144         res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1145         if (!res1) {
1146                 ret = -EINVAL;
1147                 goto out;
1148         }
1149         size = resource_size(res1);
1150         if (!devm_request_mem_region(&pdev->dev, res1->start, size,
1151                                      pdev->name)) {
1152                 ret = -EBUSY;
1153                 goto out;
1154         }
1155 
1156         telm_conf->ioss_config.ssram_base_addr = res1->start;
1157         telm_conf->ioss_config.ssram_size = size;
1158 
1159         telm_conf->pss_config.regmap = ioremap_nocache(
1160                                         telm_conf->pss_config.ssram_base_addr,
1161                                         telm_conf->pss_config.ssram_size);
1162         if (!telm_conf->pss_config.regmap) {
1163                 ret = -ENOMEM;
1164                 goto out;
1165         }
1166 
1167         telm_conf->ioss_config.regmap = ioremap_nocache(
1168                                 telm_conf->ioss_config.ssram_base_addr,
1169                                 telm_conf->ioss_config.ssram_size);
1170         if (!telm_conf->ioss_config.regmap) {
1171                 ret = -ENOMEM;
1172                 goto out;
1173         }
1174 
1175         mutex_init(&telm_conf->telem_lock);
1176         mutex_init(&telm_conf->telem_trace_lock);
1177 
1178         ret = telemetry_setup(pdev);
1179         if (ret)
1180                 goto out;
1181 
1182         ret = telemetry_set_pltdata(&telm_pltops, telm_conf);
1183         if (ret) {
1184                 dev_err(&pdev->dev, "TELEMETRY Set Pltops Failed.\n");
1185                 goto out;
1186         }
1187 
1188         return 0;
1189 
1190 out:
1191         if (res0)
1192                 release_mem_region(res0->start, resource_size(res0));
1193         if (res1)
1194                 release_mem_region(res1->start, resource_size(res1));
1195         if (telm_conf->pss_config.regmap)
1196                 iounmap(telm_conf->pss_config.regmap);
1197         if (telm_conf->ioss_config.regmap)
1198                 iounmap(telm_conf->ioss_config.regmap);
1199         dev_err(&pdev->dev, "TELEMETRY Setup Failed.\n");
1200 
1201         return ret;
1202 }
1203 
1204 static int telemetry_pltdrv_remove(struct platform_device *pdev)
1205 {
1206         telemetry_clear_pltdata();
1207         iounmap(telm_conf->pss_config.regmap);
1208         iounmap(telm_conf->ioss_config.regmap);
1209 
1210         return 0;
1211 }
1212 
1213 static struct platform_driver telemetry_soc_driver = {
1214         .probe          = telemetry_pltdrv_probe,
1215         .remove         = telemetry_pltdrv_remove,
1216         .driver         = {
1217                 .name   = DRIVER_NAME,
1218         },
1219 };
1220 
1221 static int __init telemetry_module_init(void)
1222 {
1223         return platform_driver_register(&telemetry_soc_driver);
1224 }
1225 
1226 static void __exit telemetry_module_exit(void)
1227 {
1228         platform_driver_unregister(&telemetry_soc_driver);
1229 }
1230 
1231 device_initcall(telemetry_module_init);
1232 module_exit(telemetry_module_exit);
1233 
1234 MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
1235 MODULE_DESCRIPTION("Intel SoC Telemetry Platform Driver");
1236 MODULE_VERSION(DRIVER_VERSION);
1237 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */