root/drivers/platform/x86/intel_telemetry_debugfs.c

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

DEFINITIONS

This source file includes following definitions.
  1. telemetry_debugfs_check_evts
  2. telem_pss_states_show
  3. telem_ioss_states_show
  4. telem_soc_states_show
  5. telem_s0ix_res_get
  6. telem_pss_trc_verb_show
  7. telem_pss_trc_verb_write
  8. telem_pss_trc_verb_open
  9. telem_ioss_trc_verb_show
  10. telem_ioss_trc_verb_write
  11. telem_ioss_trc_verb_open
  12. pm_suspend_prep_cb
  13. pm_suspend_exit_cb
  14. pm_notification
  15. telemetry_debugfs_init
  16. telemetry_debugfs_exit

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Intel SOC Telemetry debugfs Driver: Currently supports APL
   4  * Copyright (c) 2015, Intel Corporation.
   5  * All Rights Reserved.
   6  *
   7  * This file provides the debugfs interfaces for telemetry.
   8  * /sys/kernel/debug/telemetry/pss_info: Shows Primary Control Sub-Sys Counters
   9  * /sys/kernel/debug/telemetry/ioss_info: Shows IO Sub-System Counters
  10  * /sys/kernel/debug/telemetry/soc_states: Shows SoC State
  11  * /sys/kernel/debug/telemetry/pss_trace_verbosity: Read and Change Tracing
  12  *                              Verbosity via firmware
  13  * /sys/kernel/debug/telemetry/ioss_race_verbosity: Write and Change Tracing
  14  *                              Verbosity via firmware
  15  */
  16 #include <linux/debugfs.h>
  17 #include <linux/device.h>
  18 #include <linux/module.h>
  19 #include <linux/pci.h>
  20 #include <linux/seq_file.h>
  21 #include <linux/suspend.h>
  22 
  23 #include <asm/cpu_device_id.h>
  24 #include <asm/intel-family.h>
  25 #include <asm/intel_pmc_ipc.h>
  26 #include <asm/intel_telemetry.h>
  27 
  28 #define DRIVER_NAME                     "telemetry_soc_debugfs"
  29 #define DRIVER_VERSION                  "1.0.0"
  30 
  31 /* ApolloLake SoC Event-IDs */
  32 #define TELEM_APL_PSS_PSTATES_ID        0x2802
  33 #define TELEM_APL_PSS_IDLE_ID           0x2806
  34 #define TELEM_APL_PCS_IDLE_BLOCKED_ID   0x2C00
  35 #define TELEM_APL_PCS_S0IX_BLOCKED_ID   0x2C01
  36 #define TELEM_APL_PSS_WAKEUP_ID         0x2C02
  37 #define TELEM_APL_PSS_LTR_BLOCKING_ID   0x2C03
  38 
  39 #define TELEM_APL_S0IX_TOTAL_OCC_ID     0x4000
  40 #define TELEM_APL_S0IX_SHLW_OCC_ID      0x4001
  41 #define TELEM_APL_S0IX_DEEP_OCC_ID      0x4002
  42 #define TELEM_APL_S0IX_TOTAL_RES_ID     0x4800
  43 #define TELEM_APL_S0IX_SHLW_RES_ID      0x4801
  44 #define TELEM_APL_S0IX_DEEP_RES_ID      0x4802
  45 #define TELEM_APL_D0IX_ID               0x581A
  46 #define TELEM_APL_D3_ID                 0x5819
  47 #define TELEM_APL_PG_ID                 0x5818
  48 
  49 #define TELEM_INFO_SRAMEVTS_MASK        0xFF00
  50 #define TELEM_INFO_SRAMEVTS_SHIFT       0x8
  51 #define TELEM_SSRAM_READ_TIMEOUT        10
  52 
  53 #define TELEM_MASK_BIT                  1
  54 #define TELEM_MASK_BYTE                 0xFF
  55 #define BYTES_PER_LONG                  8
  56 #define TELEM_APL_MASK_PCS_STATE        0xF
  57 
  58 /* Max events in bitmap to check for */
  59 #define TELEM_PSS_IDLE_EVTS             25
  60 #define TELEM_PSS_IDLE_BLOCKED_EVTS     20
  61 #define TELEM_PSS_S0IX_BLOCKED_EVTS     20
  62 #define TELEM_PSS_S0IX_WAKEUP_EVTS      20
  63 #define TELEM_PSS_LTR_BLOCKING_EVTS     20
  64 #define TELEM_IOSS_DX_D0IX_EVTS         25
  65 #define TELEM_IOSS_PG_EVTS              30
  66 
  67 #define TELEM_CHECK_AND_PARSE_EVTS(EVTID, EVTNUM, BUF, EVTLOG, EVTDAT, MASK) { \
  68         if (evtlog[index].telem_evtid == (EVTID)) { \
  69                 for (idx = 0; idx < (EVTNUM); idx++) \
  70                         (BUF)[idx] = ((EVTLOG) >> (EVTDAT)[idx].bit_pos) & \
  71                                      (MASK); \
  72         continue; \
  73         } \
  74 }
  75 
  76 #define TELEM_CHECK_AND_PARSE_CTRS(EVTID, CTR) { \
  77         if (evtlog[index].telem_evtid == (EVTID)) { \
  78                 (CTR) = evtlog[index].telem_evtlog; \
  79                 continue; \
  80         } \
  81 }
  82 
  83 static u8 suspend_prep_ok;
  84 static u32 suspend_shlw_ctr_temp, suspend_deep_ctr_temp;
  85 static u64 suspend_shlw_res_temp, suspend_deep_res_temp;
  86 
  87 struct telemetry_susp_stats {
  88         u32 shlw_ctr;
  89         u32 deep_ctr;
  90         u64 shlw_res;
  91         u64 deep_res;
  92 };
  93 
  94 /* Bitmap definitions for default counters in APL */
  95 struct telem_pss_idle_stateinfo {
  96         const char *name;
  97         u32 bit_pos;
  98 };
  99 
 100 static struct telem_pss_idle_stateinfo telem_apl_pss_idle_data[] = {
 101         {"IA_CORE0_C1E",                0},
 102         {"IA_CORE1_C1E",                1},
 103         {"IA_CORE2_C1E",                2},
 104         {"IA_CORE3_C1E",                3},
 105         {"IA_CORE0_C6",                 16},
 106         {"IA_CORE1_C6",                 17},
 107         {"IA_CORE2_C6",                 18},
 108         {"IA_CORE3_C6",                 19},
 109         {"IA_MODULE0_C7",               32},
 110         {"IA_MODULE1_C7",               33},
 111         {"GT_RC6",                      40},
 112         {"IUNIT_PROCESSING_IDLE",       41},
 113         {"FAR_MEM_IDLE",                43},
 114         {"DISPLAY_IDLE",                44},
 115         {"IUNIT_INPUT_SYSTEM_IDLE",     45},
 116         {"PCS_STATUS",                  60},
 117 };
 118 
 119 struct telem_pcs_blkd_info {
 120         const char *name;
 121         u32 bit_pos;
 122 };
 123 
 124 static struct telem_pcs_blkd_info telem_apl_pcs_idle_blkd_data[] = {
 125         {"COMPUTE",                     0},
 126         {"MISC",                        8},
 127         {"MODULE_ACTIONS_PENDING",      16},
 128         {"LTR",                         24},
 129         {"DISPLAY_WAKE",                32},
 130         {"ISP_WAKE",                    40},
 131         {"PSF0_ACTIVE",                 48},
 132 };
 133 
 134 static struct telem_pcs_blkd_info telem_apl_pcs_s0ix_blkd_data[] = {
 135         {"LTR",                         0},
 136         {"IRTL",                        8},
 137         {"WAKE_DEADLINE_PENDING",       16},
 138         {"DISPLAY",                     24},
 139         {"ISP",                         32},
 140         {"CORE",                        40},
 141         {"PMC",                         48},
 142         {"MISC",                        56},
 143 };
 144 
 145 struct telem_pss_ltr_info {
 146         const char *name;
 147         u32 bit_pos;
 148 };
 149 
 150 static struct telem_pss_ltr_info telem_apl_pss_ltr_data[] = {
 151         {"CORE_ACTIVE",         0},
 152         {"MEM_UP",              8},
 153         {"DFX",                 16},
 154         {"DFX_FORCE_LTR",       24},
 155         {"DISPLAY",             32},
 156         {"ISP",                 40},
 157         {"SOUTH",               48},
 158 };
 159 
 160 struct telem_pss_wakeup_info {
 161         const char *name;
 162         u32 bit_pos;
 163 };
 164 
 165 static struct telem_pss_wakeup_info telem_apl_pss_wakeup[] = {
 166         {"IP_IDLE",                     0},
 167         {"DISPLAY_WAKE",                8},
 168         {"VOLTAGE_REG_INT",             16},
 169         {"DROWSY_TIMER (HOTPLUG)",      24},
 170         {"CORE_WAKE",                   32},
 171         {"MISC_S0IX",                   40},
 172         {"MISC_ABORT",                  56},
 173 };
 174 
 175 struct telem_ioss_d0ix_stateinfo {
 176         const char *name;
 177         u32 bit_pos;
 178 };
 179 
 180 static struct telem_ioss_d0ix_stateinfo telem_apl_ioss_d0ix_data[] = {
 181         {"CSE",         0},
 182         {"SCC2",        1},
 183         {"GMM",         2},
 184         {"XDCI",        3},
 185         {"XHCI",        4},
 186         {"ISH",         5},
 187         {"AVS",         6},
 188         {"PCIE0P1",     7},
 189         {"PECI0P0",     8},
 190         {"LPSS",        9},
 191         {"SCC",         10},
 192         {"PWM",         11},
 193         {"PCIE1_P3",    12},
 194         {"PCIE1_P2",    13},
 195         {"PCIE1_P1",    14},
 196         {"PCIE1_P0",    15},
 197         {"CNV",         16},
 198         {"SATA",        17},
 199         {"PRTC",        18},
 200 };
 201 
 202 struct telem_ioss_pg_info {
 203         const char *name;
 204         u32 bit_pos;
 205 };
 206 
 207 static struct telem_ioss_pg_info telem_apl_ioss_pg_data[] = {
 208         {"LPSS",        0},
 209         {"SCC",         1},
 210         {"P2SB",        2},
 211         {"SCC2",        3},
 212         {"GMM",         4},
 213         {"PCIE0",       5},
 214         {"XDCI",        6},
 215         {"xHCI",        7},
 216         {"CSE",         8},
 217         {"SPI",         9},
 218         {"AVSPGD4",     10},
 219         {"AVSPGD3",     11},
 220         {"AVSPGD2",     12},
 221         {"AVSPGD1",     13},
 222         {"ISH",         14},
 223         {"EXI",         15},
 224         {"NPKVRC",      16},
 225         {"NPKVNN",      17},
 226         {"CUNIT",       18},
 227         {"FUSE_CTRL",   19},
 228         {"PCIE1",       20},
 229         {"CNV",         21},
 230         {"LPC",         22},
 231         {"SATA",        23},
 232         {"SMB",         24},
 233         {"PRTC",        25},
 234 };
 235 
 236 struct telemetry_debugfs_conf {
 237         struct telemetry_susp_stats suspend_stats;
 238         struct dentry *telemetry_dbg_dir;
 239 
 240         /* Bitmap Data */
 241         struct telem_ioss_d0ix_stateinfo *ioss_d0ix_data;
 242         struct telem_pss_idle_stateinfo *pss_idle_data;
 243         struct telem_pcs_blkd_info *pcs_idle_blkd_data;
 244         struct telem_pcs_blkd_info *pcs_s0ix_blkd_data;
 245         struct telem_pss_wakeup_info *pss_wakeup;
 246         struct telem_pss_ltr_info *pss_ltr_data;
 247         struct telem_ioss_pg_info *ioss_pg_data;
 248         u8 pcs_idle_blkd_evts;
 249         u8 pcs_s0ix_blkd_evts;
 250         u8 pss_wakeup_evts;
 251         u8 pss_idle_evts;
 252         u8 pss_ltr_evts;
 253         u8 ioss_d0ix_evts;
 254         u8 ioss_pg_evts;
 255 
 256         /* IDs */
 257         u16  pss_ltr_blocking_id;
 258         u16  pcs_idle_blkd_id;
 259         u16  pcs_s0ix_blkd_id;
 260         u16  s0ix_total_occ_id;
 261         u16  s0ix_shlw_occ_id;
 262         u16  s0ix_deep_occ_id;
 263         u16  s0ix_total_res_id;
 264         u16  s0ix_shlw_res_id;
 265         u16  s0ix_deep_res_id;
 266         u16  pss_wakeup_id;
 267         u16  ioss_d0ix_id;
 268         u16  pstates_id;
 269         u16  pss_idle_id;
 270         u16  ioss_d3_id;
 271         u16  ioss_pg_id;
 272 };
 273 
 274 static struct telemetry_debugfs_conf *debugfs_conf;
 275 
 276 static struct telemetry_debugfs_conf telem_apl_debugfs_conf = {
 277         .pss_idle_data = telem_apl_pss_idle_data,
 278         .pcs_idle_blkd_data = telem_apl_pcs_idle_blkd_data,
 279         .pcs_s0ix_blkd_data = telem_apl_pcs_s0ix_blkd_data,
 280         .pss_ltr_data = telem_apl_pss_ltr_data,
 281         .pss_wakeup = telem_apl_pss_wakeup,
 282         .ioss_d0ix_data = telem_apl_ioss_d0ix_data,
 283         .ioss_pg_data = telem_apl_ioss_pg_data,
 284 
 285         .pss_idle_evts = ARRAY_SIZE(telem_apl_pss_idle_data),
 286         .pcs_idle_blkd_evts = ARRAY_SIZE(telem_apl_pcs_idle_blkd_data),
 287         .pcs_s0ix_blkd_evts = ARRAY_SIZE(telem_apl_pcs_s0ix_blkd_data),
 288         .pss_ltr_evts = ARRAY_SIZE(telem_apl_pss_ltr_data),
 289         .pss_wakeup_evts = ARRAY_SIZE(telem_apl_pss_wakeup),
 290         .ioss_d0ix_evts = ARRAY_SIZE(telem_apl_ioss_d0ix_data),
 291         .ioss_pg_evts = ARRAY_SIZE(telem_apl_ioss_pg_data),
 292 
 293         .pstates_id = TELEM_APL_PSS_PSTATES_ID,
 294         .pss_idle_id = TELEM_APL_PSS_IDLE_ID,
 295         .pcs_idle_blkd_id = TELEM_APL_PCS_IDLE_BLOCKED_ID,
 296         .pcs_s0ix_blkd_id = TELEM_APL_PCS_S0IX_BLOCKED_ID,
 297         .pss_wakeup_id = TELEM_APL_PSS_WAKEUP_ID,
 298         .pss_ltr_blocking_id = TELEM_APL_PSS_LTR_BLOCKING_ID,
 299         .s0ix_total_occ_id = TELEM_APL_S0IX_TOTAL_OCC_ID,
 300         .s0ix_shlw_occ_id = TELEM_APL_S0IX_SHLW_OCC_ID,
 301         .s0ix_deep_occ_id = TELEM_APL_S0IX_DEEP_OCC_ID,
 302         .s0ix_total_res_id = TELEM_APL_S0IX_TOTAL_RES_ID,
 303         .s0ix_shlw_res_id = TELEM_APL_S0IX_SHLW_RES_ID,
 304         .s0ix_deep_res_id = TELEM_APL_S0IX_DEEP_RES_ID,
 305         .ioss_d0ix_id = TELEM_APL_D0IX_ID,
 306         .ioss_d3_id = TELEM_APL_D3_ID,
 307         .ioss_pg_id = TELEM_APL_PG_ID,
 308 };
 309 
 310 static const struct x86_cpu_id telemetry_debugfs_cpu_ids[] = {
 311         INTEL_CPU_FAM6(ATOM_GOLDMONT, telem_apl_debugfs_conf),
 312         INTEL_CPU_FAM6(ATOM_GOLDMONT_PLUS, telem_apl_debugfs_conf),
 313         {}
 314 };
 315 
 316 MODULE_DEVICE_TABLE(x86cpu, telemetry_debugfs_cpu_ids);
 317 
 318 static int telemetry_debugfs_check_evts(void)
 319 {
 320         if ((debugfs_conf->pss_idle_evts > TELEM_PSS_IDLE_EVTS) ||
 321             (debugfs_conf->pcs_idle_blkd_evts > TELEM_PSS_IDLE_BLOCKED_EVTS) ||
 322             (debugfs_conf->pcs_s0ix_blkd_evts > TELEM_PSS_S0IX_BLOCKED_EVTS) ||
 323             (debugfs_conf->pss_ltr_evts > TELEM_PSS_LTR_BLOCKING_EVTS) ||
 324             (debugfs_conf->pss_wakeup_evts > TELEM_PSS_S0IX_WAKEUP_EVTS) ||
 325             (debugfs_conf->ioss_d0ix_evts > TELEM_IOSS_DX_D0IX_EVTS) ||
 326             (debugfs_conf->ioss_pg_evts > TELEM_IOSS_PG_EVTS))
 327                 return -EINVAL;
 328 
 329         return 0;
 330 }
 331 
 332 static int telem_pss_states_show(struct seq_file *s, void *unused)
 333 {
 334         struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
 335         struct telemetry_debugfs_conf *conf = debugfs_conf;
 336         const char *name[TELEM_MAX_OS_ALLOCATED_EVENTS];
 337         u32 pcs_idle_blkd[TELEM_PSS_IDLE_BLOCKED_EVTS],
 338             pcs_s0ix_blkd[TELEM_PSS_S0IX_BLOCKED_EVTS],
 339             pss_s0ix_wakeup[TELEM_PSS_S0IX_WAKEUP_EVTS],
 340             pss_ltr_blkd[TELEM_PSS_LTR_BLOCKING_EVTS],
 341             pss_idle[TELEM_PSS_IDLE_EVTS];
 342         int index, idx, ret, err = 0;
 343         u64 pstates = 0;
 344 
 345         ret = telemetry_read_eventlog(TELEM_PSS, evtlog,
 346                                       TELEM_MAX_OS_ALLOCATED_EVENTS);
 347         if (ret < 0)
 348                 return ret;
 349 
 350         err = telemetry_get_evtname(TELEM_PSS, name,
 351                                     TELEM_MAX_OS_ALLOCATED_EVENTS);
 352         if (err < 0)
 353                 return err;
 354 
 355         seq_puts(s, "\n----------------------------------------------------\n");
 356         seq_puts(s, "\tPSS TELEM EVENTLOG (Residency = field/19.2 us\n");
 357         seq_puts(s, "----------------------------------------------------\n");
 358         for (index = 0; index < ret; index++) {
 359                 seq_printf(s, "%-32s %llu\n",
 360                            name[index], evtlog[index].telem_evtlog);
 361 
 362                 /* Fetch PSS IDLE State */
 363                 if (evtlog[index].telem_evtid == conf->pss_idle_id) {
 364                         pss_idle[conf->pss_idle_evts - 1] =
 365                         (evtlog[index].telem_evtlog >>
 366                         conf->pss_idle_data[conf->pss_idle_evts - 1].bit_pos) &
 367                         TELEM_APL_MASK_PCS_STATE;
 368                 }
 369 
 370                 TELEM_CHECK_AND_PARSE_EVTS(conf->pss_idle_id,
 371                                            conf->pss_idle_evts - 1,
 372                                            pss_idle, evtlog[index].telem_evtlog,
 373                                            conf->pss_idle_data, TELEM_MASK_BIT);
 374 
 375                 TELEM_CHECK_AND_PARSE_EVTS(conf->pcs_idle_blkd_id,
 376                                            conf->pcs_idle_blkd_evts,
 377                                            pcs_idle_blkd,
 378                                            evtlog[index].telem_evtlog,
 379                                            conf->pcs_idle_blkd_data,
 380                                            TELEM_MASK_BYTE);
 381 
 382                 TELEM_CHECK_AND_PARSE_EVTS(conf->pcs_s0ix_blkd_id,
 383                                            conf->pcs_s0ix_blkd_evts,
 384                                            pcs_s0ix_blkd,
 385                                            evtlog[index].telem_evtlog,
 386                                            conf->pcs_s0ix_blkd_data,
 387                                            TELEM_MASK_BYTE);
 388 
 389                 TELEM_CHECK_AND_PARSE_EVTS(conf->pss_wakeup_id,
 390                                            conf->pss_wakeup_evts,
 391                                            pss_s0ix_wakeup,
 392                                            evtlog[index].telem_evtlog,
 393                                            conf->pss_wakeup, TELEM_MASK_BYTE);
 394 
 395                 TELEM_CHECK_AND_PARSE_EVTS(conf->pss_ltr_blocking_id,
 396                                            conf->pss_ltr_evts, pss_ltr_blkd,
 397                                            evtlog[index].telem_evtlog,
 398                                            conf->pss_ltr_data, TELEM_MASK_BYTE);
 399 
 400                 if (evtlog[index].telem_evtid == debugfs_conf->pstates_id)
 401                         pstates = evtlog[index].telem_evtlog;
 402         }
 403 
 404         seq_puts(s, "\n--------------------------------------\n");
 405         seq_puts(s, "PStates\n");
 406         seq_puts(s, "--------------------------------------\n");
 407         seq_puts(s, "Domain\t\t\t\tFreq(Mhz)\n");
 408         seq_printf(s, " IA\t\t\t\t %llu\n GT\t\t\t\t %llu\n",
 409                    (pstates & TELEM_MASK_BYTE)*100,
 410                    ((pstates >> 8) & TELEM_MASK_BYTE)*50/3);
 411 
 412         seq_printf(s, " IUNIT\t\t\t\t %llu\n SA\t\t\t\t %llu\n",
 413                    ((pstates >> 16) & TELEM_MASK_BYTE)*25,
 414                    ((pstates >> 24) & TELEM_MASK_BYTE)*50/3);
 415 
 416         seq_puts(s, "\n--------------------------------------\n");
 417         seq_puts(s, "PSS IDLE Status\n");
 418         seq_puts(s, "--------------------------------------\n");
 419         seq_puts(s, "Device\t\t\t\t\tIDLE\n");
 420         for (index = 0; index < debugfs_conf->pss_idle_evts; index++) {
 421                 seq_printf(s, "%-32s\t%u\n",
 422                            debugfs_conf->pss_idle_data[index].name,
 423                            pss_idle[index]);
 424         }
 425 
 426         seq_puts(s, "\n--------------------------------------\n");
 427         seq_puts(s, "PSS Idle blkd Status (~1ms saturating bucket)\n");
 428         seq_puts(s, "--------------------------------------\n");
 429         seq_puts(s, "Blocker\t\t\t\t\tCount\n");
 430         for (index = 0; index < debugfs_conf->pcs_idle_blkd_evts; index++) {
 431                 seq_printf(s, "%-32s\t%u\n",
 432                            debugfs_conf->pcs_idle_blkd_data[index].name,
 433                            pcs_idle_blkd[index]);
 434         }
 435 
 436         seq_puts(s, "\n--------------------------------------\n");
 437         seq_puts(s, "PSS S0ix blkd Status (~1ms saturating bucket)\n");
 438         seq_puts(s, "--------------------------------------\n");
 439         seq_puts(s, "Blocker\t\t\t\t\tCount\n");
 440         for (index = 0; index < debugfs_conf->pcs_s0ix_blkd_evts; index++) {
 441                 seq_printf(s, "%-32s\t%u\n",
 442                            debugfs_conf->pcs_s0ix_blkd_data[index].name,
 443                            pcs_s0ix_blkd[index]);
 444         }
 445 
 446         seq_puts(s, "\n--------------------------------------\n");
 447         seq_puts(s, "LTR Blocking Status (~1ms saturating bucket)\n");
 448         seq_puts(s, "--------------------------------------\n");
 449         seq_puts(s, "Blocker\t\t\t\t\tCount\n");
 450         for (index = 0; index < debugfs_conf->pss_ltr_evts; index++) {
 451                 seq_printf(s, "%-32s\t%u\n",
 452                            debugfs_conf->pss_ltr_data[index].name,
 453                            pss_s0ix_wakeup[index]);
 454         }
 455 
 456         seq_puts(s, "\n--------------------------------------\n");
 457         seq_puts(s, "Wakes Status (~1ms saturating bucket)\n");
 458         seq_puts(s, "--------------------------------------\n");
 459         seq_puts(s, "Wakes\t\t\t\t\tCount\n");
 460         for (index = 0; index < debugfs_conf->pss_wakeup_evts; index++) {
 461                 seq_printf(s, "%-32s\t%u\n",
 462                            debugfs_conf->pss_wakeup[index].name,
 463                            pss_ltr_blkd[index]);
 464         }
 465 
 466         return 0;
 467 }
 468 
 469 DEFINE_SHOW_ATTRIBUTE(telem_pss_states);
 470 
 471 static int telem_ioss_states_show(struct seq_file *s, void *unused)
 472 {
 473         struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
 474         const char *name[TELEM_MAX_OS_ALLOCATED_EVENTS];
 475         int index, ret, err;
 476 
 477         ret = telemetry_read_eventlog(TELEM_IOSS, evtlog,
 478                                       TELEM_MAX_OS_ALLOCATED_EVENTS);
 479         if (ret < 0)
 480                 return ret;
 481 
 482         err = telemetry_get_evtname(TELEM_IOSS, name,
 483                                     TELEM_MAX_OS_ALLOCATED_EVENTS);
 484         if (err < 0)
 485                 return err;
 486 
 487         seq_puts(s, "--------------------------------------\n");
 488         seq_puts(s, "\tI0SS TELEMETRY EVENTLOG\n");
 489         seq_puts(s, "--------------------------------------\n");
 490         for (index = 0; index < ret; index++) {
 491                 seq_printf(s, "%-32s 0x%llx\n",
 492                            name[index], evtlog[index].telem_evtlog);
 493         }
 494 
 495         return 0;
 496 }
 497 
 498 DEFINE_SHOW_ATTRIBUTE(telem_ioss_states);
 499 
 500 static int telem_soc_states_show(struct seq_file *s, void *unused)
 501 {
 502         u32 d3_sts[TELEM_IOSS_DX_D0IX_EVTS], d0ix_sts[TELEM_IOSS_DX_D0IX_EVTS];
 503         u32 pg_sts[TELEM_IOSS_PG_EVTS], pss_idle[TELEM_PSS_IDLE_EVTS];
 504         struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
 505         u32 s0ix_total_ctr = 0, s0ix_shlw_ctr = 0, s0ix_deep_ctr = 0;
 506         u64 s0ix_total_res = 0, s0ix_shlw_res = 0, s0ix_deep_res = 0;
 507         struct telemetry_debugfs_conf *conf = debugfs_conf;
 508         struct pci_dev *dev = NULL;
 509         int index, idx, ret;
 510         u32 d3_state;
 511         u16 pmcsr;
 512 
 513         ret = telemetry_read_eventlog(TELEM_IOSS, evtlog,
 514                                       TELEM_MAX_OS_ALLOCATED_EVENTS);
 515         if (ret < 0)
 516                 return ret;
 517 
 518         for (index = 0; index < ret; index++) {
 519                 TELEM_CHECK_AND_PARSE_EVTS(conf->ioss_d3_id,
 520                                            conf->ioss_d0ix_evts,
 521                                            d3_sts, evtlog[index].telem_evtlog,
 522                                            conf->ioss_d0ix_data,
 523                                            TELEM_MASK_BIT);
 524 
 525                 TELEM_CHECK_AND_PARSE_EVTS(conf->ioss_pg_id, conf->ioss_pg_evts,
 526                                            pg_sts, evtlog[index].telem_evtlog,
 527                                            conf->ioss_pg_data, TELEM_MASK_BIT);
 528 
 529                 TELEM_CHECK_AND_PARSE_EVTS(conf->ioss_d0ix_id,
 530                                            conf->ioss_d0ix_evts,
 531                                            d0ix_sts, evtlog[index].telem_evtlog,
 532                                            conf->ioss_d0ix_data,
 533                                            TELEM_MASK_BIT);
 534 
 535                 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_total_occ_id,
 536                                            s0ix_total_ctr);
 537 
 538                 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_occ_id,
 539                                            s0ix_shlw_ctr);
 540 
 541                 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_occ_id,
 542                                            s0ix_deep_ctr);
 543 
 544                 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_total_res_id,
 545                                            s0ix_total_res);
 546 
 547                 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_res_id,
 548                                            s0ix_shlw_res);
 549 
 550                 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_res_id,
 551                                            s0ix_deep_res);
 552         }
 553 
 554         seq_puts(s, "\n---------------------------------------------------\n");
 555         seq_puts(s, "S0IX Type\t\t\t Occurrence\t\t Residency(us)\n");
 556         seq_puts(s, "---------------------------------------------------\n");
 557 
 558         seq_printf(s, "S0IX Shallow\t\t\t %10u\t %10llu\n",
 559                    s0ix_shlw_ctr -
 560                    conf->suspend_stats.shlw_ctr,
 561                    (u64)((s0ix_shlw_res -
 562                    conf->suspend_stats.shlw_res)*10/192));
 563 
 564         seq_printf(s, "S0IX Deep\t\t\t %10u\t %10llu\n",
 565                    s0ix_deep_ctr -
 566                    conf->suspend_stats.deep_ctr,
 567                    (u64)((s0ix_deep_res -
 568                    conf->suspend_stats.deep_res)*10/192));
 569 
 570         seq_printf(s, "Suspend(With S0ixShallow)\t %10u\t %10llu\n",
 571                    conf->suspend_stats.shlw_ctr,
 572                    (u64)(conf->suspend_stats.shlw_res*10)/192);
 573 
 574         seq_printf(s, "Suspend(With S0ixDeep)\t\t %10u\t %10llu\n",
 575                    conf->suspend_stats.deep_ctr,
 576                    (u64)(conf->suspend_stats.deep_res*10)/192);
 577 
 578         seq_printf(s, "TOTAL S0IX\t\t\t %10u\t %10llu\n", s0ix_total_ctr,
 579                    (u64)(s0ix_total_res*10/192));
 580         seq_puts(s, "\n-------------------------------------------------\n");
 581         seq_puts(s, "\t\tDEVICE STATES\n");
 582         seq_puts(s, "-------------------------------------------------\n");
 583 
 584         for_each_pci_dev(dev) {
 585                 pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
 586                 d3_state = ((pmcsr & PCI_PM_CTRL_STATE_MASK) ==
 587                             (__force int)PCI_D3hot) ? 1 : 0;
 588 
 589                 seq_printf(s, "pci %04x %04X %s %20.20s: ",
 590                            dev->vendor, dev->device, dev_name(&dev->dev),
 591                            dev_driver_string(&dev->dev));
 592                 seq_printf(s, " d3:%x\n", d3_state);
 593         }
 594 
 595         seq_puts(s, "\n--------------------------------------\n");
 596         seq_puts(s, "D3/D0i3 Status\n");
 597         seq_puts(s, "--------------------------------------\n");
 598         seq_puts(s, "Block\t\t D3\t D0i3\n");
 599         for (index = 0; index < conf->ioss_d0ix_evts; index++) {
 600                 seq_printf(s, "%-10s\t %u\t %u\n",
 601                            conf->ioss_d0ix_data[index].name,
 602                            d3_sts[index], d0ix_sts[index]);
 603         }
 604 
 605         seq_puts(s, "\n--------------------------------------\n");
 606         seq_puts(s, "South Complex PowerGate Status\n");
 607         seq_puts(s, "--------------------------------------\n");
 608         seq_puts(s, "Device\t\t PG\n");
 609         for (index = 0; index < conf->ioss_pg_evts; index++) {
 610                 seq_printf(s, "%-10s\t %u\n",
 611                            conf->ioss_pg_data[index].name,
 612                            pg_sts[index]);
 613         }
 614 
 615         evtlog->telem_evtid = conf->pss_idle_id;
 616         ret = telemetry_read_events(TELEM_PSS, evtlog, 1);
 617         if (ret < 0)
 618                 return ret;
 619 
 620         seq_puts(s, "\n-----------------------------------------\n");
 621         seq_puts(s, "North Idle Status\n");
 622         seq_puts(s, "-----------------------------------------\n");
 623         for (idx = 0; idx < conf->pss_idle_evts - 1; idx++) {
 624                 pss_idle[idx] = (evtlog->telem_evtlog >>
 625                                 conf->pss_idle_data[idx].bit_pos) &
 626                                 TELEM_MASK_BIT;
 627         }
 628 
 629         pss_idle[idx] = (evtlog->telem_evtlog >>
 630                         conf->pss_idle_data[idx].bit_pos) &
 631                         TELEM_APL_MASK_PCS_STATE;
 632 
 633         for (index = 0; index < conf->pss_idle_evts; index++) {
 634                 seq_printf(s, "%-30s %u\n",
 635                            conf->pss_idle_data[index].name,
 636                            pss_idle[index]);
 637         }
 638 
 639         seq_puts(s, "\nPCS_STATUS Code\n");
 640         seq_puts(s, "0:C0 1:C1 2:C1_DN_WT_DEV 3:C2 4:C2_WT_DE_MEM_UP\n");
 641         seq_puts(s, "5:C2_WT_DE_MEM_DOWN 6:C2_UP_WT_DEV 7:C2_DN 8:C2_VOA\n");
 642         seq_puts(s, "9:C2_VOA_UP 10:S0IX_PRE 11:S0IX\n");
 643 
 644         return 0;
 645 }
 646 
 647 DEFINE_SHOW_ATTRIBUTE(telem_soc_states);
 648 
 649 static int telem_s0ix_res_get(void *data, u64 *val)
 650 {
 651         u64 s0ix_total_res;
 652         int ret;
 653 
 654         ret = intel_pmc_s0ix_counter_read(&s0ix_total_res);
 655         if (ret) {
 656                 pr_err("Failed to read S0ix residency");
 657                 return ret;
 658         }
 659 
 660         *val = s0ix_total_res;
 661 
 662         return 0;
 663 }
 664 
 665 DEFINE_DEBUGFS_ATTRIBUTE(telem_s0ix_fops, telem_s0ix_res_get, NULL, "%llu\n");
 666 
 667 static int telem_pss_trc_verb_show(struct seq_file *s, void *unused)
 668 {
 669         u32 verbosity;
 670         int err;
 671 
 672         err = telemetry_get_trace_verbosity(TELEM_PSS, &verbosity);
 673         if (err) {
 674                 pr_err("Get PSS Trace Verbosity Failed with Error %d\n", err);
 675                 return -EFAULT;
 676         }
 677 
 678         seq_printf(s, "PSS Trace Verbosity %u\n", verbosity);
 679         return 0;
 680 }
 681 
 682 static ssize_t telem_pss_trc_verb_write(struct file *file,
 683                                         const char __user *userbuf,
 684                                         size_t count, loff_t *ppos)
 685 {
 686         u32 verbosity;
 687         int err;
 688 
 689         if (kstrtou32_from_user(userbuf, count, 0, &verbosity))
 690                 return -EFAULT;
 691 
 692         err = telemetry_set_trace_verbosity(TELEM_PSS, verbosity);
 693         if (err) {
 694                 pr_err("Changing PSS Trace Verbosity Failed. Error %d\n", err);
 695                 count = err;
 696         }
 697 
 698         return count;
 699 }
 700 
 701 static int telem_pss_trc_verb_open(struct inode *inode, struct file *file)
 702 {
 703         return single_open(file, telem_pss_trc_verb_show, inode->i_private);
 704 }
 705 
 706 static const struct file_operations telem_pss_trc_verb_ops = {
 707         .open           = telem_pss_trc_verb_open,
 708         .read           = seq_read,
 709         .write          = telem_pss_trc_verb_write,
 710         .llseek         = seq_lseek,
 711         .release        = single_release,
 712 };
 713 
 714 static int telem_ioss_trc_verb_show(struct seq_file *s, void *unused)
 715 {
 716         u32 verbosity;
 717         int err;
 718 
 719         err = telemetry_get_trace_verbosity(TELEM_IOSS, &verbosity);
 720         if (err) {
 721                 pr_err("Get IOSS Trace Verbosity Failed with Error %d\n", err);
 722                 return -EFAULT;
 723         }
 724 
 725         seq_printf(s, "IOSS Trace Verbosity %u\n", verbosity);
 726         return 0;
 727 }
 728 
 729 static ssize_t telem_ioss_trc_verb_write(struct file *file,
 730                                          const char __user *userbuf,
 731                                          size_t count, loff_t *ppos)
 732 {
 733         u32 verbosity;
 734         int err;
 735 
 736         if (kstrtou32_from_user(userbuf, count, 0, &verbosity))
 737                 return -EFAULT;
 738 
 739         err = telemetry_set_trace_verbosity(TELEM_IOSS, verbosity);
 740         if (err) {
 741                 pr_err("Changing IOSS Trace Verbosity Failed. Error %d\n", err);
 742                 count = err;
 743         }
 744 
 745         return count;
 746 }
 747 
 748 static int telem_ioss_trc_verb_open(struct inode *inode, struct file *file)
 749 {
 750         return single_open(file, telem_ioss_trc_verb_show, inode->i_private);
 751 }
 752 
 753 static const struct file_operations telem_ioss_trc_verb_ops = {
 754         .open           = telem_ioss_trc_verb_open,
 755         .read           = seq_read,
 756         .write          = telem_ioss_trc_verb_write,
 757         .llseek         = seq_lseek,
 758         .release        = single_release,
 759 };
 760 
 761 static int pm_suspend_prep_cb(void)
 762 {
 763         struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
 764         struct telemetry_debugfs_conf *conf = debugfs_conf;
 765         int ret, index;
 766 
 767         ret = telemetry_raw_read_eventlog(TELEM_IOSS, evtlog,
 768                         TELEM_MAX_OS_ALLOCATED_EVENTS);
 769         if (ret < 0) {
 770                 suspend_prep_ok = 0;
 771                 goto out;
 772         }
 773 
 774         for (index = 0; index < ret; index++) {
 775 
 776                 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_occ_id,
 777                                            suspend_shlw_ctr_temp);
 778 
 779                 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_occ_id,
 780                                            suspend_deep_ctr_temp);
 781 
 782                 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_res_id,
 783                                            suspend_shlw_res_temp);
 784 
 785                 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_res_id,
 786                                            suspend_deep_res_temp);
 787         }
 788         suspend_prep_ok = 1;
 789 out:
 790         return NOTIFY_OK;
 791 }
 792 
 793 static int pm_suspend_exit_cb(void)
 794 {
 795         struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
 796         static u32 suspend_shlw_ctr_exit, suspend_deep_ctr_exit;
 797         static u64 suspend_shlw_res_exit, suspend_deep_res_exit;
 798         struct telemetry_debugfs_conf *conf = debugfs_conf;
 799         int ret, index;
 800 
 801         if (!suspend_prep_ok)
 802                 goto out;
 803 
 804         ret = telemetry_raw_read_eventlog(TELEM_IOSS, evtlog,
 805                                           TELEM_MAX_OS_ALLOCATED_EVENTS);
 806         if (ret < 0)
 807                 goto out;
 808 
 809         for (index = 0; index < ret; index++) {
 810                 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_occ_id,
 811                                            suspend_shlw_ctr_exit);
 812 
 813                 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_occ_id,
 814                                            suspend_deep_ctr_exit);
 815 
 816                 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_res_id,
 817                                            suspend_shlw_res_exit);
 818 
 819                 TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_res_id,
 820                                            suspend_deep_res_exit);
 821         }
 822 
 823         if ((suspend_shlw_ctr_exit < suspend_shlw_ctr_temp) ||
 824             (suspend_deep_ctr_exit < suspend_deep_ctr_temp) ||
 825             (suspend_shlw_res_exit < suspend_shlw_res_temp) ||
 826             (suspend_deep_res_exit < suspend_deep_res_temp)) {
 827                 pr_err("Wrong s0ix counters detected\n");
 828                 goto out;
 829         }
 830 
 831         /*
 832          * Due to some design limitations in the firmware, sometimes the
 833          * counters do not get updated by the time we reach here. As a
 834          * workaround, we try to see if this was a genuine case of sleep
 835          * failure or not by cross-checking from PMC GCR registers directly.
 836          */
 837         if (suspend_shlw_ctr_exit == suspend_shlw_ctr_temp &&
 838             suspend_deep_ctr_exit == suspend_deep_ctr_temp) {
 839                 ret = intel_pmc_gcr_read64(PMC_GCR_TELEM_SHLW_S0IX_REG,
 840                                           &suspend_shlw_res_exit);
 841                 if (ret < 0)
 842                         goto out;
 843 
 844                 ret = intel_pmc_gcr_read64(PMC_GCR_TELEM_DEEP_S0IX_REG,
 845                                           &suspend_deep_res_exit);
 846                 if (ret < 0)
 847                         goto out;
 848 
 849                 if (suspend_shlw_res_exit > suspend_shlw_res_temp)
 850                         suspend_shlw_ctr_exit++;
 851 
 852                 if (suspend_deep_res_exit > suspend_deep_res_temp)
 853                         suspend_deep_ctr_exit++;
 854         }
 855 
 856         suspend_shlw_ctr_exit -= suspend_shlw_ctr_temp;
 857         suspend_deep_ctr_exit -= suspend_deep_ctr_temp;
 858         suspend_shlw_res_exit -= suspend_shlw_res_temp;
 859         suspend_deep_res_exit -= suspend_deep_res_temp;
 860 
 861         if (suspend_shlw_ctr_exit != 0) {
 862                 conf->suspend_stats.shlw_ctr +=
 863                 suspend_shlw_ctr_exit;
 864 
 865                 conf->suspend_stats.shlw_res +=
 866                 suspend_shlw_res_exit;
 867         }
 868 
 869         if (suspend_deep_ctr_exit != 0) {
 870                 conf->suspend_stats.deep_ctr +=
 871                 suspend_deep_ctr_exit;
 872 
 873                 conf->suspend_stats.deep_res +=
 874                 suspend_deep_res_exit;
 875         }
 876 
 877 out:
 878         suspend_prep_ok = 0;
 879         return NOTIFY_OK;
 880 }
 881 
 882 static int pm_notification(struct notifier_block *this,
 883                            unsigned long event, void *ptr)
 884 {
 885         switch (event) {
 886         case PM_SUSPEND_PREPARE:
 887                 return pm_suspend_prep_cb();
 888         case PM_POST_SUSPEND:
 889                 return pm_suspend_exit_cb();
 890         }
 891 
 892         return NOTIFY_DONE;
 893 }
 894 
 895 static struct notifier_block pm_notifier = {
 896         .notifier_call = pm_notification,
 897 };
 898 
 899 static int __init telemetry_debugfs_init(void)
 900 {
 901         const struct x86_cpu_id *id;
 902         int err;
 903         struct dentry *dir;
 904 
 905         /* Only APL supported for now */
 906         id = x86_match_cpu(telemetry_debugfs_cpu_ids);
 907         if (!id)
 908                 return -ENODEV;
 909 
 910         debugfs_conf = (struct telemetry_debugfs_conf *)id->driver_data;
 911 
 912         err = telemetry_pltconfig_valid();
 913         if (err < 0) {
 914                 pr_info("Invalid pltconfig, ensure IPC1 device is enabled in BIOS\n");
 915                 return -ENODEV;
 916         }
 917 
 918         err = telemetry_debugfs_check_evts();
 919         if (err < 0) {
 920                 pr_info("telemetry_debugfs_check_evts failed\n");
 921                 return -EINVAL;
 922         }
 923 
 924         register_pm_notifier(&pm_notifier);
 925 
 926         dir = debugfs_create_dir("telemetry", NULL);
 927         debugfs_conf->telemetry_dbg_dir = dir;
 928 
 929         debugfs_create_file("pss_info", S_IFREG | S_IRUGO, dir, NULL,
 930                             &telem_pss_states_fops);
 931         debugfs_create_file("ioss_info", S_IFREG | S_IRUGO, dir, NULL,
 932                             &telem_ioss_states_fops);
 933         debugfs_create_file("soc_states", S_IFREG | S_IRUGO, dir, NULL,
 934                             &telem_soc_states_fops);
 935         debugfs_create_file("s0ix_residency_usec", S_IFREG | S_IRUGO, dir, NULL,
 936                             &telem_s0ix_fops);
 937         debugfs_create_file("pss_trace_verbosity", S_IFREG | S_IRUGO, dir, NULL,
 938                             &telem_pss_trc_verb_ops);
 939         debugfs_create_file("ioss_trace_verbosity", S_IFREG | S_IRUGO, dir,
 940                             NULL, &telem_ioss_trc_verb_ops);
 941         return 0;
 942 }
 943 
 944 static void __exit telemetry_debugfs_exit(void)
 945 {
 946         debugfs_remove_recursive(debugfs_conf->telemetry_dbg_dir);
 947         debugfs_conf->telemetry_dbg_dir = NULL;
 948         unregister_pm_notifier(&pm_notifier);
 949 }
 950 
 951 late_initcall(telemetry_debugfs_init);
 952 module_exit(telemetry_debugfs_exit);
 953 
 954 MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
 955 MODULE_DESCRIPTION("Intel SoC Telemetry debugfs Interface");
 956 MODULE_VERSION(DRIVER_VERSION);
 957 MODULE_LICENSE("GPL v2");

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