0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/io.h>
0013 #include <linux/module.h>
0014 #include <linux/platform_device.h>
0015
0016 #include <asm/cpu_device_id.h>
0017 #include <asm/intel-family.h>
0018 #include <asm/intel_punit_ipc.h>
0019 #include <asm/intel_telemetry.h>
0020
0021 #define DRIVER_NAME "intel_telemetry"
0022 #define DRIVER_VERSION "1.0.0"
0023
0024 #define TELEM_TRC_VERBOSITY_MASK 0x3
0025
0026 #define TELEM_MIN_PERIOD(x) ((x) & 0x7F0000)
0027 #define TELEM_MAX_PERIOD(x) ((x) & 0x7F000000)
0028 #define TELEM_SAMPLE_PERIOD_INVALID(x) ((x) & (BIT(7)))
0029 #define TELEM_CLEAR_SAMPLE_PERIOD(x) ((x) &= ~0x7F)
0030
0031 #define TELEM_SAMPLING_DEFAULT_PERIOD 0xD
0032
0033 #define TELEM_MAX_EVENTS_SRAM 28
0034 #define TELEM_SSRAM_STARTTIME_OFFSET 8
0035 #define TELEM_SSRAM_EVTLOG_OFFSET 16
0036
0037 #define IOSS_TELEM 0xeb
0038 #define IOSS_TELEM_EVENT_READ 0x0
0039 #define IOSS_TELEM_EVENT_WRITE 0x1
0040 #define IOSS_TELEM_INFO_READ 0x2
0041 #define IOSS_TELEM_TRACE_CTL_READ 0x5
0042 #define IOSS_TELEM_TRACE_CTL_WRITE 0x6
0043 #define IOSS_TELEM_EVENT_CTL_READ 0x7
0044 #define IOSS_TELEM_EVENT_CTL_WRITE 0x8
0045 #define IOSS_TELEM_EVT_WRITE_SIZE 0x3
0046
0047 #define TELEM_INFO_SRAMEVTS_MASK 0xFF00
0048 #define TELEM_INFO_SRAMEVTS_SHIFT 0x8
0049 #define TELEM_SSRAM_READ_TIMEOUT 10
0050
0051 #define TELEM_INFO_NENABLES_MASK 0xFF
0052 #define TELEM_EVENT_ENABLE 0x8000
0053
0054 #define TELEM_MASK_BIT 1
0055 #define TELEM_MASK_BYTE 0xFF
0056 #define BYTES_PER_LONG 8
0057 #define TELEM_MASK_PCS_STATE 0xF
0058
0059 #define TELEM_DISABLE(x) ((x) &= ~(BIT(31)))
0060 #define TELEM_CLEAR_EVENTS(x) ((x) |= (BIT(30)))
0061 #define TELEM_ENABLE_SRAM_EVT_TRACE(x) ((x) &= ~(BIT(30) | BIT(24)))
0062 #define TELEM_ENABLE_PERIODIC(x) ((x) |= (BIT(23) | BIT(31) | BIT(7)))
0063 #define TELEM_EXTRACT_VERBOSITY(x, y) ((y) = (((x) >> 27) & 0x3))
0064 #define TELEM_CLEAR_VERBOSITY_BITS(x) ((x) &= ~(BIT(27) | BIT(28)))
0065 #define TELEM_SET_VERBOSITY_BITS(x, y) ((x) |= ((y) << 27))
0066
0067 enum telemetry_action {
0068 TELEM_UPDATE = 0,
0069 TELEM_ADD,
0070 TELEM_RESET,
0071 TELEM_ACTION_NONE
0072 };
0073
0074 struct telem_ssram_region {
0075 u64 timestamp;
0076 u64 start_time;
0077 u64 events[TELEM_MAX_EVENTS_SRAM];
0078 };
0079
0080 static struct telemetry_plt_config *telm_conf;
0081
0082
0083
0084
0085
0086 static struct telemetry_evtmap
0087 telemetry_apl_ioss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = {
0088 {"SOC_S0IX_TOTAL_RES", 0x4800},
0089 {"SOC_S0IX_TOTAL_OCC", 0x4000},
0090 {"SOC_S0IX_SHALLOW_RES", 0x4801},
0091 {"SOC_S0IX_SHALLOW_OCC", 0x4001},
0092 {"SOC_S0IX_DEEP_RES", 0x4802},
0093 {"SOC_S0IX_DEEP_OCC", 0x4002},
0094 {"PMC_POWER_GATE", 0x5818},
0095 {"PMC_D3_STATES", 0x5819},
0096 {"PMC_D0I3_STATES", 0x581A},
0097 {"PMC_S0IX_WAKE_REASON_GPIO", 0x6000},
0098 {"PMC_S0IX_WAKE_REASON_TIMER", 0x6001},
0099 {"PMC_S0IX_WAKE_REASON_VNNREQ", 0x6002},
0100 {"PMC_S0IX_WAKE_REASON_LOWPOWER", 0x6003},
0101 {"PMC_S0IX_WAKE_REASON_EXTERNAL", 0x6004},
0102 {"PMC_S0IX_WAKE_REASON_MISC", 0x6005},
0103 {"PMC_S0IX_BLOCKING_IPS_D3_D0I3", 0x6006},
0104 {"PMC_S0IX_BLOCKING_IPS_PG", 0x6007},
0105 {"PMC_S0IX_BLOCKING_MISC_IPS_PG", 0x6008},
0106 {"PMC_S0IX_BLOCK_IPS_VNN_REQ", 0x6009},
0107 {"PMC_S0IX_BLOCK_IPS_CLOCKS", 0x600B},
0108 };
0109
0110
0111 static struct telemetry_evtmap
0112 telemetry_apl_pss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = {
0113 {"IA_CORE0_C6_RES", 0x0400},
0114 {"IA_CORE0_C6_CTR", 0x0000},
0115 {"IA_MODULE0_C7_RES", 0x0410},
0116 {"IA_MODULE0_C7_CTR", 0x000E},
0117 {"IA_C0_RES", 0x0805},
0118 {"PCS_LTR", 0x2801},
0119 {"PSTATES", 0x2802},
0120 {"SOC_S0I3_RES", 0x0409},
0121 {"SOC_S0I3_CTR", 0x000A},
0122 {"PCS_S0I3_CTR", 0x0009},
0123 {"PCS_C1E_RES", 0x041A},
0124 {"PCS_IDLE_STATUS", 0x2806},
0125 {"IA_PERF_LIMITS", 0x280B},
0126 {"GT_PERF_LIMITS", 0x280C},
0127 {"PCS_WAKEUP_S0IX_CTR", 0x0030},
0128 {"PCS_IDLE_BLOCKED", 0x2C00},
0129 {"PCS_S0IX_BLOCKED", 0x2C01},
0130 {"PCS_S0IX_WAKE_REASONS", 0x2C02},
0131 {"PCS_LTR_BLOCKING", 0x2C03},
0132 {"PC2_AND_MEM_SHALLOW_IDLE_RES", 0x1D40},
0133 };
0134
0135 static struct telemetry_evtmap
0136 telemetry_glk_pss_default_events[TELEM_MAX_OS_ALLOCATED_EVENTS] = {
0137 {"IA_CORE0_C6_RES", 0x0400},
0138 {"IA_CORE0_C6_CTR", 0x0000},
0139 {"IA_MODULE0_C7_RES", 0x0410},
0140 {"IA_MODULE0_C7_CTR", 0x000C},
0141 {"IA_C0_RES", 0x0805},
0142 {"PCS_LTR", 0x2801},
0143 {"PSTATES", 0x2802},
0144 {"SOC_S0I3_RES", 0x0407},
0145 {"SOC_S0I3_CTR", 0x0008},
0146 {"PCS_S0I3_CTR", 0x0007},
0147 {"PCS_C1E_RES", 0x0414},
0148 {"PCS_IDLE_STATUS", 0x2806},
0149 {"IA_PERF_LIMITS", 0x280B},
0150 {"GT_PERF_LIMITS", 0x280C},
0151 {"PCS_WAKEUP_S0IX_CTR", 0x0025},
0152 {"PCS_IDLE_BLOCKED", 0x2C00},
0153 {"PCS_S0IX_BLOCKED", 0x2C01},
0154 {"PCS_S0IX_WAKE_REASONS", 0x2C02},
0155 {"PCS_LTR_BLOCKING", 0x2C03},
0156 {"PC2_AND_MEM_SHALLOW_IDLE_RES", 0x1D40},
0157 };
0158
0159
0160 static struct telemetry_plt_config telem_apl_config = {
0161 .pss_config = {
0162 .telem_evts = telemetry_apl_pss_default_events,
0163 },
0164 .ioss_config = {
0165 .telem_evts = telemetry_apl_ioss_default_events,
0166 },
0167 };
0168
0169
0170 static struct telemetry_plt_config telem_glk_config = {
0171 .pss_config = {
0172 .telem_evts = telemetry_glk_pss_default_events,
0173 },
0174 .ioss_config = {
0175 .telem_evts = telemetry_apl_ioss_default_events,
0176 },
0177 };
0178
0179 static const struct x86_cpu_id telemetry_cpu_ids[] = {
0180 X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT, &telem_apl_config),
0181 X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_PLUS, &telem_glk_config),
0182 {}
0183 };
0184
0185 MODULE_DEVICE_TABLE(x86cpu, telemetry_cpu_ids);
0186
0187 static inline int telem_get_unitconfig(enum telemetry_unit telem_unit,
0188 struct telemetry_unit_config **unit_config)
0189 {
0190 if (telem_unit == TELEM_PSS)
0191 *unit_config = &(telm_conf->pss_config);
0192 else if (telem_unit == TELEM_IOSS)
0193 *unit_config = &(telm_conf->ioss_config);
0194 else
0195 return -EINVAL;
0196
0197 return 0;
0198
0199 }
0200
0201 static int telemetry_check_evtid(enum telemetry_unit telem_unit,
0202 u32 *evtmap, u8 len,
0203 enum telemetry_action action)
0204 {
0205 struct telemetry_unit_config *unit_config;
0206 int ret;
0207
0208 ret = telem_get_unitconfig(telem_unit, &unit_config);
0209 if (ret < 0)
0210 return ret;
0211
0212 switch (action) {
0213 case TELEM_RESET:
0214 if (len > TELEM_MAX_EVENTS_SRAM)
0215 return -EINVAL;
0216
0217 break;
0218
0219 case TELEM_UPDATE:
0220 if (len > TELEM_MAX_EVENTS_SRAM)
0221 return -EINVAL;
0222
0223 if ((len > 0) && (evtmap == NULL))
0224 return -EINVAL;
0225
0226 break;
0227
0228 case TELEM_ADD:
0229 if ((len + unit_config->ssram_evts_used) >
0230 TELEM_MAX_EVENTS_SRAM)
0231 return -EINVAL;
0232
0233 if ((len > 0) && (evtmap == NULL))
0234 return -EINVAL;
0235
0236 break;
0237
0238 default:
0239 pr_err("Unknown Telemetry action specified %d\n", action);
0240 return -EINVAL;
0241 }
0242
0243 return 0;
0244 }
0245
0246
0247 static inline int telemetry_plt_config_ioss_event(u32 evt_id, int index)
0248 {
0249 u32 write_buf;
0250
0251 write_buf = evt_id | TELEM_EVENT_ENABLE;
0252 write_buf <<= BITS_PER_BYTE;
0253 write_buf |= index;
0254
0255 return intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM,
0256 IOSS_TELEM_EVENT_WRITE, &write_buf,
0257 IOSS_TELEM_EVT_WRITE_SIZE, NULL, 0);
0258 }
0259
0260 static inline int telemetry_plt_config_pss_event(u32 evt_id, int index)
0261 {
0262 u32 write_buf;
0263 int ret;
0264
0265 write_buf = evt_id | TELEM_EVENT_ENABLE;
0266 ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT,
0267 index, 0, &write_buf, NULL);
0268
0269 return ret;
0270 }
0271
0272 static int telemetry_setup_iossevtconfig(struct telemetry_evtconfig evtconfig,
0273 enum telemetry_action action)
0274 {
0275 struct intel_scu_ipc_dev *scu = telm_conf->scu;
0276 u8 num_ioss_evts, ioss_period;
0277 int ret, index, idx;
0278 u32 *ioss_evtmap;
0279 u32 telem_ctrl;
0280
0281 num_ioss_evts = evtconfig.num_evts;
0282 ioss_period = evtconfig.period;
0283 ioss_evtmap = evtconfig.evtmap;
0284
0285
0286 ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
0287 IOSS_TELEM_EVENT_CTL_READ, NULL, 0,
0288 &telem_ctrl, sizeof(telem_ctrl));
0289 if (ret) {
0290 pr_err("IOSS TELEM_CTRL Read Failed\n");
0291 return ret;
0292 }
0293
0294
0295 TELEM_DISABLE(telem_ctrl);
0296
0297 ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
0298 IOSS_TELEM_EVENT_CTL_WRITE, &telem_ctrl,
0299 sizeof(telem_ctrl), NULL, 0);
0300 if (ret) {
0301 pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
0302 return ret;
0303 }
0304
0305
0306
0307 if (action == TELEM_RESET) {
0308
0309 TELEM_CLEAR_EVENTS(telem_ctrl);
0310
0311 ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
0312 IOSS_TELEM_EVENT_CTL_WRITE,
0313 &telem_ctrl, sizeof(telem_ctrl),
0314 NULL, 0);
0315 if (ret) {
0316 pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
0317 return ret;
0318 }
0319 telm_conf->ioss_config.ssram_evts_used = 0;
0320
0321
0322 for (idx = 0; idx < num_ioss_evts; idx++) {
0323 if (telemetry_plt_config_ioss_event(
0324 telm_conf->ioss_config.telem_evts[idx].evt_id,
0325 idx)) {
0326 pr_err("IOSS TELEM_RESET Fail for data: %x\n",
0327 telm_conf->ioss_config.telem_evts[idx].evt_id);
0328 continue;
0329 }
0330 telm_conf->ioss_config.ssram_evts_used++;
0331 }
0332 }
0333
0334
0335 if (action == TELEM_UPDATE) {
0336
0337 TELEM_CLEAR_EVENTS(telem_ctrl);
0338
0339 ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
0340 IOSS_TELEM_EVENT_CTL_WRITE,
0341 &telem_ctrl, sizeof(telem_ctrl),
0342 NULL, 0);
0343 if (ret) {
0344 pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
0345 return ret;
0346 }
0347 telm_conf->ioss_config.ssram_evts_used = 0;
0348
0349
0350 for (index = 0; index < num_ioss_evts; index++) {
0351 telm_conf->ioss_config.telem_evts[index].evt_id =
0352 ioss_evtmap[index];
0353
0354 if (telemetry_plt_config_ioss_event(
0355 telm_conf->ioss_config.telem_evts[index].evt_id,
0356 index)) {
0357 pr_err("IOSS TELEM_UPDATE Fail for Evt%x\n",
0358 ioss_evtmap[index]);
0359 continue;
0360 }
0361 telm_conf->ioss_config.ssram_evts_used++;
0362 }
0363 }
0364
0365
0366 if (action == TELEM_ADD) {
0367
0368 for (index = telm_conf->ioss_config.ssram_evts_used, idx = 0;
0369 idx < num_ioss_evts; index++, idx++) {
0370 telm_conf->ioss_config.telem_evts[index].evt_id =
0371 ioss_evtmap[idx];
0372
0373 if (telemetry_plt_config_ioss_event(
0374 telm_conf->ioss_config.telem_evts[index].evt_id,
0375 index)) {
0376 pr_err("IOSS TELEM_ADD Fail for Event %x\n",
0377 ioss_evtmap[idx]);
0378 continue;
0379 }
0380 telm_conf->ioss_config.ssram_evts_used++;
0381 }
0382 }
0383
0384
0385 TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
0386 TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
0387 TELEM_ENABLE_PERIODIC(telem_ctrl);
0388 telem_ctrl |= ioss_period;
0389
0390 ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
0391 IOSS_TELEM_EVENT_CTL_WRITE,
0392 &telem_ctrl, sizeof(telem_ctrl), NULL, 0);
0393 if (ret) {
0394 pr_err("IOSS TELEM_CTRL Event Enable Write Failed\n");
0395 return ret;
0396 }
0397
0398 telm_conf->ioss_config.curr_period = ioss_period;
0399
0400 return 0;
0401 }
0402
0403
0404 static int telemetry_setup_pssevtconfig(struct telemetry_evtconfig evtconfig,
0405 enum telemetry_action action)
0406 {
0407 u8 num_pss_evts, pss_period;
0408 int ret, index, idx;
0409 u32 *pss_evtmap;
0410 u32 telem_ctrl;
0411
0412 num_pss_evts = evtconfig.num_evts;
0413 pss_period = evtconfig.period;
0414 pss_evtmap = evtconfig.evtmap;
0415
0416
0417
0418 ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL,
0419 0, 0, NULL, &telem_ctrl);
0420 if (ret) {
0421 pr_err("PSS TELEM_CTRL Read Failed\n");
0422 return ret;
0423 }
0424
0425
0426 TELEM_DISABLE(telem_ctrl);
0427 ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
0428 0, 0, &telem_ctrl, NULL);
0429 if (ret) {
0430 pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
0431 return ret;
0432 }
0433
0434
0435 if (action == TELEM_RESET) {
0436
0437 TELEM_CLEAR_EVENTS(telem_ctrl);
0438
0439 ret = intel_punit_ipc_command(
0440 IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
0441 0, 0, &telem_ctrl, NULL);
0442 if (ret) {
0443 pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
0444 return ret;
0445 }
0446 telm_conf->pss_config.ssram_evts_used = 0;
0447
0448 for (idx = 0; idx < num_pss_evts; idx++) {
0449 if (telemetry_plt_config_pss_event(
0450 telm_conf->pss_config.telem_evts[idx].evt_id,
0451 idx)) {
0452 pr_err("PSS TELEM_RESET Fail for Event %x\n",
0453 telm_conf->pss_config.telem_evts[idx].evt_id);
0454 continue;
0455 }
0456 telm_conf->pss_config.ssram_evts_used++;
0457 }
0458 }
0459
0460
0461 if (action == TELEM_UPDATE) {
0462
0463 TELEM_CLEAR_EVENTS(telem_ctrl);
0464
0465 ret = intel_punit_ipc_command(
0466 IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
0467 0, 0, &telem_ctrl, NULL);
0468 if (ret) {
0469 pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
0470 return ret;
0471 }
0472 telm_conf->pss_config.ssram_evts_used = 0;
0473
0474
0475 for (index = 0; index < num_pss_evts; index++) {
0476 telm_conf->pss_config.telem_evts[index].evt_id =
0477 pss_evtmap[index];
0478
0479 if (telemetry_plt_config_pss_event(
0480 telm_conf->pss_config.telem_evts[index].evt_id,
0481 index)) {
0482 pr_err("PSS TELEM_UPDATE Fail for Event %x\n",
0483 pss_evtmap[index]);
0484 continue;
0485 }
0486 telm_conf->pss_config.ssram_evts_used++;
0487 }
0488 }
0489
0490
0491 if (action == TELEM_ADD) {
0492
0493 for (index = telm_conf->pss_config.ssram_evts_used, idx = 0;
0494 idx < num_pss_evts; index++, idx++) {
0495
0496 telm_conf->pss_config.telem_evts[index].evt_id =
0497 pss_evtmap[idx];
0498
0499 if (telemetry_plt_config_pss_event(
0500 telm_conf->pss_config.telem_evts[index].evt_id,
0501 index)) {
0502 pr_err("PSS TELEM_ADD Fail for Event %x\n",
0503 pss_evtmap[idx]);
0504 continue;
0505 }
0506 telm_conf->pss_config.ssram_evts_used++;
0507 }
0508 }
0509
0510
0511 TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
0512 TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
0513 TELEM_ENABLE_PERIODIC(telem_ctrl);
0514 telem_ctrl |= pss_period;
0515
0516 ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
0517 0, 0, &telem_ctrl, NULL);
0518 if (ret) {
0519 pr_err("PSS TELEM_CTRL Event Enable Write Failed\n");
0520 return ret;
0521 }
0522
0523 telm_conf->pss_config.curr_period = pss_period;
0524
0525 return 0;
0526 }
0527
0528 static int telemetry_setup_evtconfig(struct telemetry_evtconfig pss_evtconfig,
0529 struct telemetry_evtconfig ioss_evtconfig,
0530 enum telemetry_action action)
0531 {
0532 int ret;
0533
0534 mutex_lock(&(telm_conf->telem_lock));
0535
0536 if ((action == TELEM_UPDATE) && (telm_conf->telem_in_use)) {
0537 ret = -EBUSY;
0538 goto out;
0539 }
0540
0541 ret = telemetry_check_evtid(TELEM_PSS, pss_evtconfig.evtmap,
0542 pss_evtconfig.num_evts, action);
0543 if (ret)
0544 goto out;
0545
0546 ret = telemetry_check_evtid(TELEM_IOSS, ioss_evtconfig.evtmap,
0547 ioss_evtconfig.num_evts, action);
0548 if (ret)
0549 goto out;
0550
0551 if (ioss_evtconfig.num_evts) {
0552 ret = telemetry_setup_iossevtconfig(ioss_evtconfig, action);
0553 if (ret)
0554 goto out;
0555 }
0556
0557 if (pss_evtconfig.num_evts) {
0558 ret = telemetry_setup_pssevtconfig(pss_evtconfig, action);
0559 if (ret)
0560 goto out;
0561 }
0562
0563 if ((action == TELEM_UPDATE) || (action == TELEM_ADD))
0564 telm_conf->telem_in_use = true;
0565 else
0566 telm_conf->telem_in_use = false;
0567
0568 out:
0569 mutex_unlock(&(telm_conf->telem_lock));
0570 return ret;
0571 }
0572
0573 static int telemetry_setup(struct platform_device *pdev)
0574 {
0575 struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig;
0576 u32 read_buf, events, event_regs;
0577 int ret;
0578
0579 ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM,
0580 IOSS_TELEM_INFO_READ, NULL, 0,
0581 &read_buf, sizeof(read_buf));
0582 if (ret) {
0583 dev_err(&pdev->dev, "IOSS TELEM_INFO Read Failed\n");
0584 return ret;
0585 }
0586
0587
0588 events = (read_buf & TELEM_INFO_SRAMEVTS_MASK) >>
0589 TELEM_INFO_SRAMEVTS_SHIFT;
0590 event_regs = read_buf & TELEM_INFO_NENABLES_MASK;
0591 if ((events < TELEM_MAX_EVENTS_SRAM) ||
0592 (event_regs < TELEM_MAX_EVENTS_SRAM)) {
0593 dev_err(&pdev->dev, "IOSS:Insufficient Space for SRAM Trace\n");
0594 dev_err(&pdev->dev, "SRAM Events %d; Event Regs %d\n",
0595 events, event_regs);
0596 return -ENOMEM;
0597 }
0598
0599 telm_conf->ioss_config.min_period = TELEM_MIN_PERIOD(read_buf);
0600 telm_conf->ioss_config.max_period = TELEM_MAX_PERIOD(read_buf);
0601
0602
0603 ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_READ_TELE_INFO, 0, 0,
0604 NULL, &read_buf);
0605 if (ret) {
0606 dev_err(&pdev->dev, "PSS TELEM_INFO Read Failed\n");
0607 return ret;
0608 }
0609
0610
0611 events = (read_buf & TELEM_INFO_SRAMEVTS_MASK) >>
0612 TELEM_INFO_SRAMEVTS_SHIFT;
0613 event_regs = read_buf & TELEM_INFO_SRAMEVTS_MASK;
0614 if ((events < TELEM_MAX_EVENTS_SRAM) ||
0615 (event_regs < TELEM_MAX_EVENTS_SRAM)) {
0616 dev_err(&pdev->dev, "PSS:Insufficient Space for SRAM Trace\n");
0617 dev_err(&pdev->dev, "SRAM Events %d; Event Regs %d\n",
0618 events, event_regs);
0619 return -ENOMEM;
0620 }
0621
0622 telm_conf->pss_config.min_period = TELEM_MIN_PERIOD(read_buf);
0623 telm_conf->pss_config.max_period = TELEM_MAX_PERIOD(read_buf);
0624
0625 pss_evtconfig.evtmap = NULL;
0626 pss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
0627 pss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
0628
0629 ioss_evtconfig.evtmap = NULL;
0630 ioss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
0631 ioss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
0632
0633 ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
0634 TELEM_RESET);
0635 if (ret) {
0636 dev_err(&pdev->dev, "TELEMETRY Setup Failed\n");
0637 return ret;
0638 }
0639 return 0;
0640 }
0641
0642 static int telemetry_plt_update_events(struct telemetry_evtconfig pss_evtconfig,
0643 struct telemetry_evtconfig ioss_evtconfig)
0644 {
0645 int ret;
0646
0647 if ((pss_evtconfig.num_evts > 0) &&
0648 (TELEM_SAMPLE_PERIOD_INVALID(pss_evtconfig.period))) {
0649 pr_err("PSS Sampling Period Out of Range\n");
0650 return -EINVAL;
0651 }
0652
0653 if ((ioss_evtconfig.num_evts > 0) &&
0654 (TELEM_SAMPLE_PERIOD_INVALID(ioss_evtconfig.period))) {
0655 pr_err("IOSS Sampling Period Out of Range\n");
0656 return -EINVAL;
0657 }
0658
0659 ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
0660 TELEM_UPDATE);
0661 if (ret)
0662 pr_err("TELEMETRY Config Failed\n");
0663
0664 return ret;
0665 }
0666
0667
0668 static int telemetry_plt_set_sampling_period(u8 pss_period, u8 ioss_period)
0669 {
0670 u32 telem_ctrl = 0;
0671 int ret = 0;
0672
0673 mutex_lock(&(telm_conf->telem_lock));
0674 if (ioss_period) {
0675 struct intel_scu_ipc_dev *scu = telm_conf->scu;
0676
0677 if (TELEM_SAMPLE_PERIOD_INVALID(ioss_period)) {
0678 pr_err("IOSS Sampling Period Out of Range\n");
0679 ret = -EINVAL;
0680 goto out;
0681 }
0682
0683
0684 ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
0685 IOSS_TELEM_EVENT_CTL_READ, NULL, 0,
0686 &telem_ctrl, sizeof(telem_ctrl));
0687 if (ret) {
0688 pr_err("IOSS TELEM_CTRL Read Failed\n");
0689 goto out;
0690 }
0691
0692
0693 TELEM_DISABLE(telem_ctrl);
0694
0695 ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
0696 IOSS_TELEM_EVENT_CTL_WRITE,
0697 &telem_ctrl, sizeof(telem_ctrl),
0698 NULL, 0);
0699 if (ret) {
0700 pr_err("IOSS TELEM_CTRL Event Disable Write Failed\n");
0701 goto out;
0702 }
0703
0704
0705 TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
0706 TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
0707 TELEM_ENABLE_PERIODIC(telem_ctrl);
0708 telem_ctrl |= ioss_period;
0709
0710 ret = intel_scu_ipc_dev_command(scu, IOSS_TELEM,
0711 IOSS_TELEM_EVENT_CTL_WRITE,
0712 &telem_ctrl, sizeof(telem_ctrl),
0713 NULL, 0);
0714 if (ret) {
0715 pr_err("IOSS TELEM_CTRL Event Enable Write Failed\n");
0716 goto out;
0717 }
0718 telm_conf->ioss_config.curr_period = ioss_period;
0719 }
0720
0721 if (pss_period) {
0722 if (TELEM_SAMPLE_PERIOD_INVALID(pss_period)) {
0723 pr_err("PSS Sampling Period Out of Range\n");
0724 ret = -EINVAL;
0725 goto out;
0726 }
0727
0728
0729 ret = intel_punit_ipc_command(
0730 IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL,
0731 0, 0, NULL, &telem_ctrl);
0732 if (ret) {
0733 pr_err("PSS TELEM_CTRL Read Failed\n");
0734 goto out;
0735 }
0736
0737
0738 TELEM_DISABLE(telem_ctrl);
0739 ret = intel_punit_ipc_command(
0740 IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
0741 0, 0, &telem_ctrl, NULL);
0742 if (ret) {
0743 pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
0744 goto out;
0745 }
0746
0747
0748 TELEM_CLEAR_SAMPLE_PERIOD(telem_ctrl);
0749 TELEM_ENABLE_SRAM_EVT_TRACE(telem_ctrl);
0750 TELEM_ENABLE_PERIODIC(telem_ctrl);
0751 telem_ctrl |= pss_period;
0752
0753 ret = intel_punit_ipc_command(
0754 IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
0755 0, 0, &telem_ctrl, NULL);
0756 if (ret) {
0757 pr_err("PSS TELEM_CTRL Event Enable Write Failed\n");
0758 goto out;
0759 }
0760 telm_conf->pss_config.curr_period = pss_period;
0761 }
0762
0763 out:
0764 mutex_unlock(&(telm_conf->telem_lock));
0765 return ret;
0766 }
0767
0768
0769 static int telemetry_plt_get_sampling_period(u8 *pss_min_period,
0770 u8 *pss_max_period,
0771 u8 *ioss_min_period,
0772 u8 *ioss_max_period)
0773 {
0774 *pss_min_period = telm_conf->pss_config.min_period;
0775 *pss_max_period = telm_conf->pss_config.max_period;
0776 *ioss_min_period = telm_conf->ioss_config.min_period;
0777 *ioss_max_period = telm_conf->ioss_config.max_period;
0778
0779 return 0;
0780 }
0781
0782
0783 static int telemetry_plt_reset_events(void)
0784 {
0785 struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig;
0786 int ret;
0787
0788 pss_evtconfig.evtmap = NULL;
0789 pss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
0790 pss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
0791
0792 ioss_evtconfig.evtmap = NULL;
0793 ioss_evtconfig.num_evts = TELEM_MAX_OS_ALLOCATED_EVENTS;
0794 ioss_evtconfig.period = TELEM_SAMPLING_DEFAULT_PERIOD;
0795
0796 ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
0797 TELEM_RESET);
0798 if (ret)
0799 pr_err("TELEMETRY Reset Failed\n");
0800
0801 return ret;
0802 }
0803
0804
0805 static int telemetry_plt_get_eventconfig(struct telemetry_evtconfig *pss_config,
0806 struct telemetry_evtconfig *ioss_config,
0807 int pss_len, int ioss_len)
0808 {
0809 u32 *pss_evtmap, *ioss_evtmap;
0810 u32 index;
0811
0812 pss_evtmap = pss_config->evtmap;
0813 ioss_evtmap = ioss_config->evtmap;
0814
0815 mutex_lock(&(telm_conf->telem_lock));
0816 pss_config->num_evts = telm_conf->pss_config.ssram_evts_used;
0817 ioss_config->num_evts = telm_conf->ioss_config.ssram_evts_used;
0818
0819 pss_config->period = telm_conf->pss_config.curr_period;
0820 ioss_config->period = telm_conf->ioss_config.curr_period;
0821
0822 if ((pss_len < telm_conf->pss_config.ssram_evts_used) ||
0823 (ioss_len < telm_conf->ioss_config.ssram_evts_used)) {
0824 mutex_unlock(&(telm_conf->telem_lock));
0825 return -EINVAL;
0826 }
0827
0828 for (index = 0; index < telm_conf->pss_config.ssram_evts_used;
0829 index++) {
0830 pss_evtmap[index] =
0831 telm_conf->pss_config.telem_evts[index].evt_id;
0832 }
0833
0834 for (index = 0; index < telm_conf->ioss_config.ssram_evts_used;
0835 index++) {
0836 ioss_evtmap[index] =
0837 telm_conf->ioss_config.telem_evts[index].evt_id;
0838 }
0839
0840 mutex_unlock(&(telm_conf->telem_lock));
0841 return 0;
0842 }
0843
0844
0845 static int telemetry_plt_add_events(u8 num_pss_evts, u8 num_ioss_evts,
0846 u32 *pss_evtmap, u32 *ioss_evtmap)
0847 {
0848 struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig;
0849 int ret;
0850
0851 pss_evtconfig.evtmap = pss_evtmap;
0852 pss_evtconfig.num_evts = num_pss_evts;
0853 pss_evtconfig.period = telm_conf->pss_config.curr_period;
0854
0855 ioss_evtconfig.evtmap = ioss_evtmap;
0856 ioss_evtconfig.num_evts = num_ioss_evts;
0857 ioss_evtconfig.period = telm_conf->ioss_config.curr_period;
0858
0859 ret = telemetry_setup_evtconfig(pss_evtconfig, ioss_evtconfig,
0860 TELEM_ADD);
0861 if (ret)
0862 pr_err("TELEMETRY ADD Failed\n");
0863
0864 return ret;
0865 }
0866
0867 static int telem_evtlog_read(enum telemetry_unit telem_unit,
0868 struct telem_ssram_region *ssram_region, u8 len)
0869 {
0870 struct telemetry_unit_config *unit_config;
0871 u64 timestamp_prev, timestamp_next;
0872 int ret, index, timeout = 0;
0873
0874 ret = telem_get_unitconfig(telem_unit, &unit_config);
0875 if (ret < 0)
0876 return ret;
0877
0878 if (len > unit_config->ssram_evts_used)
0879 len = unit_config->ssram_evts_used;
0880
0881 do {
0882 timestamp_prev = readq(unit_config->regmap);
0883 if (!timestamp_prev) {
0884 pr_err("Ssram under update. Please Try Later\n");
0885 return -EBUSY;
0886 }
0887
0888 ssram_region->start_time = readq(unit_config->regmap +
0889 TELEM_SSRAM_STARTTIME_OFFSET);
0890
0891 for (index = 0; index < len; index++) {
0892 ssram_region->events[index] =
0893 readq(unit_config->regmap + TELEM_SSRAM_EVTLOG_OFFSET +
0894 BYTES_PER_LONG*index);
0895 }
0896
0897 timestamp_next = readq(unit_config->regmap);
0898 if (!timestamp_next) {
0899 pr_err("Ssram under update. Please Try Later\n");
0900 return -EBUSY;
0901 }
0902
0903 if (timeout++ > TELEM_SSRAM_READ_TIMEOUT) {
0904 pr_err("Timeout while reading Events\n");
0905 return -EBUSY;
0906 }
0907
0908 } while (timestamp_prev != timestamp_next);
0909
0910 ssram_region->timestamp = timestamp_next;
0911
0912 return len;
0913 }
0914
0915 static int telemetry_plt_raw_read_eventlog(enum telemetry_unit telem_unit,
0916 struct telemetry_evtlog *evtlog,
0917 int len, int log_all_evts)
0918 {
0919 int index, idx1, ret, readlen = len;
0920 struct telem_ssram_region ssram_region;
0921 struct telemetry_evtmap *evtmap;
0922
0923 switch (telem_unit) {
0924 case TELEM_PSS:
0925 evtmap = telm_conf->pss_config.telem_evts;
0926 break;
0927
0928 case TELEM_IOSS:
0929 evtmap = telm_conf->ioss_config.telem_evts;
0930 break;
0931
0932 default:
0933 pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit);
0934 return -EINVAL;
0935 }
0936
0937 if (!log_all_evts)
0938 readlen = TELEM_MAX_EVENTS_SRAM;
0939
0940 ret = telem_evtlog_read(telem_unit, &ssram_region, readlen);
0941 if (ret < 0)
0942 return ret;
0943
0944
0945 if ((!log_all_evts) && (len > ret))
0946 return -EINVAL;
0947
0948 if (log_all_evts)
0949 for (index = 0; index < ret; index++) {
0950 evtlog[index].telem_evtlog = ssram_region.events[index];
0951 evtlog[index].telem_evtid = evtmap[index].evt_id;
0952 }
0953 else
0954 for (index = 0, readlen = 0; (index < ret) && (readlen < len);
0955 index++) {
0956 for (idx1 = 0; idx1 < len; idx1++) {
0957
0958 if (evtmap[index].evt_id ==
0959 evtlog[idx1].telem_evtid) {
0960 evtlog[idx1].telem_evtlog =
0961 ssram_region.events[index];
0962 readlen++;
0963
0964 break;
0965 }
0966 }
0967 }
0968
0969 return readlen;
0970 }
0971
0972 static int telemetry_plt_read_eventlog(enum telemetry_unit telem_unit,
0973 struct telemetry_evtlog *evtlog, int len, int log_all_evts)
0974 {
0975 int ret;
0976
0977 mutex_lock(&(telm_conf->telem_lock));
0978 ret = telemetry_plt_raw_read_eventlog(telem_unit, evtlog,
0979 len, log_all_evts);
0980 mutex_unlock(&(telm_conf->telem_lock));
0981
0982 return ret;
0983 }
0984
0985 static int telemetry_plt_get_trace_verbosity(enum telemetry_unit telem_unit,
0986 u32 *verbosity)
0987 {
0988 u32 temp = 0;
0989 int ret;
0990
0991 if (verbosity == NULL)
0992 return -EINVAL;
0993
0994 mutex_lock(&(telm_conf->telem_trace_lock));
0995 switch (telem_unit) {
0996 case TELEM_PSS:
0997 ret = intel_punit_ipc_command(
0998 IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL,
0999 0, 0, NULL, &temp);
1000 if (ret) {
1001 pr_err("PSS TRACE_CTRL Read Failed\n");
1002 goto out;
1003 }
1004
1005 break;
1006
1007 case TELEM_IOSS:
1008 ret = intel_scu_ipc_dev_command(telm_conf->scu,
1009 IOSS_TELEM, IOSS_TELEM_TRACE_CTL_READ,
1010 NULL, 0, &temp, sizeof(temp));
1011 if (ret) {
1012 pr_err("IOSS TRACE_CTL Read Failed\n");
1013 goto out;
1014 }
1015
1016 break;
1017
1018 default:
1019 pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit);
1020 ret = -EINVAL;
1021 break;
1022 }
1023 TELEM_EXTRACT_VERBOSITY(temp, *verbosity);
1024
1025 out:
1026 mutex_unlock(&(telm_conf->telem_trace_lock));
1027 return ret;
1028 }
1029
1030 static int telemetry_plt_set_trace_verbosity(enum telemetry_unit telem_unit,
1031 u32 verbosity)
1032 {
1033 u32 temp = 0;
1034 int ret;
1035
1036 verbosity &= TELEM_TRC_VERBOSITY_MASK;
1037
1038 mutex_lock(&(telm_conf->telem_trace_lock));
1039 switch (telem_unit) {
1040 case TELEM_PSS:
1041 ret = intel_punit_ipc_command(
1042 IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL,
1043 0, 0, NULL, &temp);
1044 if (ret) {
1045 pr_err("PSS TRACE_CTRL Read Failed\n");
1046 goto out;
1047 }
1048
1049 TELEM_CLEAR_VERBOSITY_BITS(temp);
1050 TELEM_SET_VERBOSITY_BITS(temp, verbosity);
1051
1052 ret = intel_punit_ipc_command(
1053 IPC_PUNIT_BIOS_WRITE_TELE_TRACE_CTRL,
1054 0, 0, &temp, NULL);
1055 if (ret) {
1056 pr_err("PSS TRACE_CTRL Verbosity Set Failed\n");
1057 goto out;
1058 }
1059 break;
1060
1061 case TELEM_IOSS:
1062 ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM,
1063 IOSS_TELEM_TRACE_CTL_READ,
1064 NULL, 0, &temp, sizeof(temp));
1065 if (ret) {
1066 pr_err("IOSS TRACE_CTL Read Failed\n");
1067 goto out;
1068 }
1069
1070 TELEM_CLEAR_VERBOSITY_BITS(temp);
1071 TELEM_SET_VERBOSITY_BITS(temp, verbosity);
1072
1073 ret = intel_scu_ipc_dev_command(telm_conf->scu, IOSS_TELEM,
1074 IOSS_TELEM_TRACE_CTL_WRITE,
1075 &temp, sizeof(temp), NULL, 0);
1076 if (ret) {
1077 pr_err("IOSS TRACE_CTL Verbosity Set Failed\n");
1078 goto out;
1079 }
1080 break;
1081
1082 default:
1083 pr_err("Unknown Telemetry Unit Specified %d\n", telem_unit);
1084 ret = -EINVAL;
1085 break;
1086 }
1087
1088 out:
1089 mutex_unlock(&(telm_conf->telem_trace_lock));
1090 return ret;
1091 }
1092
1093 static const struct telemetry_core_ops telm_pltops = {
1094 .get_trace_verbosity = telemetry_plt_get_trace_verbosity,
1095 .set_trace_verbosity = telemetry_plt_set_trace_verbosity,
1096 .set_sampling_period = telemetry_plt_set_sampling_period,
1097 .get_sampling_period = telemetry_plt_get_sampling_period,
1098 .raw_read_eventlog = telemetry_plt_raw_read_eventlog,
1099 .get_eventconfig = telemetry_plt_get_eventconfig,
1100 .update_events = telemetry_plt_update_events,
1101 .read_eventlog = telemetry_plt_read_eventlog,
1102 .reset_events = telemetry_plt_reset_events,
1103 .add_events = telemetry_plt_add_events,
1104 };
1105
1106 static int telemetry_pltdrv_probe(struct platform_device *pdev)
1107 {
1108 const struct x86_cpu_id *id;
1109 void __iomem *mem;
1110 int ret;
1111
1112 id = x86_match_cpu(telemetry_cpu_ids);
1113 if (!id)
1114 return -ENODEV;
1115
1116 telm_conf = (struct telemetry_plt_config *)id->driver_data;
1117
1118 telm_conf->pmc = dev_get_drvdata(pdev->dev.parent);
1119
1120 mem = devm_platform_ioremap_resource(pdev, 0);
1121 if (IS_ERR(mem))
1122 return PTR_ERR(mem);
1123
1124 telm_conf->pss_config.regmap = mem;
1125
1126 mem = devm_platform_ioremap_resource(pdev, 1);
1127 if (IS_ERR(mem))
1128 return PTR_ERR(mem);
1129
1130 telm_conf->ioss_config.regmap = mem;
1131
1132 telm_conf->scu = devm_intel_scu_ipc_dev_get(&pdev->dev);
1133 if (!telm_conf->scu) {
1134 ret = -EPROBE_DEFER;
1135 goto out;
1136 }
1137
1138 mutex_init(&telm_conf->telem_lock);
1139 mutex_init(&telm_conf->telem_trace_lock);
1140
1141 ret = telemetry_setup(pdev);
1142 if (ret)
1143 goto out;
1144
1145 ret = telemetry_set_pltdata(&telm_pltops, telm_conf);
1146 if (ret) {
1147 dev_err(&pdev->dev, "TELEMETRY Set Pltops Failed.\n");
1148 goto out;
1149 }
1150
1151 return 0;
1152
1153 out:
1154 dev_err(&pdev->dev, "TELEMETRY Setup Failed.\n");
1155
1156 return ret;
1157 }
1158
1159 static int telemetry_pltdrv_remove(struct platform_device *pdev)
1160 {
1161 telemetry_clear_pltdata();
1162 return 0;
1163 }
1164
1165 static struct platform_driver telemetry_soc_driver = {
1166 .probe = telemetry_pltdrv_probe,
1167 .remove = telemetry_pltdrv_remove,
1168 .driver = {
1169 .name = DRIVER_NAME,
1170 },
1171 };
1172
1173 static int __init telemetry_module_init(void)
1174 {
1175 return platform_driver_register(&telemetry_soc_driver);
1176 }
1177
1178 static void __exit telemetry_module_exit(void)
1179 {
1180 platform_driver_unregister(&telemetry_soc_driver);
1181 }
1182
1183 device_initcall(telemetry_module_init);
1184 module_exit(telemetry_module_exit);
1185
1186 MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
1187 MODULE_DESCRIPTION("Intel SoC Telemetry Platform Driver");
1188 MODULE_VERSION(DRIVER_VERSION);
1189 MODULE_LICENSE("GPL v2");