Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Intel SOC Telemetry debugfs Driver: Currently supports APL
0004  * Copyright (c) 2015, Intel Corporation.
0005  * All Rights Reserved.
0006  *
0007  * This file provides the debugfs interfaces for telemetry.
0008  * /sys/kernel/debug/telemetry/pss_info: Shows Primary Control Sub-Sys Counters
0009  * /sys/kernel/debug/telemetry/ioss_info: Shows IO Sub-System Counters
0010  * /sys/kernel/debug/telemetry/soc_states: Shows SoC State
0011  * /sys/kernel/debug/telemetry/pss_trace_verbosity: Read and Change Tracing
0012  *              Verbosity via firmware
0013  * /sys/kernel/debug/telemetry/ioss_race_verbosity: Write and Change Tracing
0014  *              Verbosity via firmware
0015  */
0016 #include <linux/debugfs.h>
0017 #include <linux/device.h>
0018 #include <linux/mfd/intel_pmc_bxt.h>
0019 #include <linux/module.h>
0020 #include <linux/pci.h>
0021 #include <linux/seq_file.h>
0022 #include <linux/suspend.h>
0023 
0024 #include <asm/cpu_device_id.h>
0025 #include <asm/intel-family.h>
0026 #include <asm/intel_telemetry.h>
0027 
0028 #define DRIVER_NAME         "telemetry_soc_debugfs"
0029 #define DRIVER_VERSION          "1.0.0"
0030 
0031 /* ApolloLake SoC Event-IDs */
0032 #define TELEM_APL_PSS_PSTATES_ID    0x2802
0033 #define TELEM_APL_PSS_IDLE_ID       0x2806
0034 #define TELEM_APL_PCS_IDLE_BLOCKED_ID   0x2C00
0035 #define TELEM_APL_PCS_S0IX_BLOCKED_ID   0x2C01
0036 #define TELEM_APL_PSS_WAKEUP_ID     0x2C02
0037 #define TELEM_APL_PSS_LTR_BLOCKING_ID   0x2C03
0038 
0039 #define TELEM_APL_S0IX_TOTAL_OCC_ID 0x4000
0040 #define TELEM_APL_S0IX_SHLW_OCC_ID  0x4001
0041 #define TELEM_APL_S0IX_DEEP_OCC_ID  0x4002
0042 #define TELEM_APL_S0IX_TOTAL_RES_ID 0x4800
0043 #define TELEM_APL_S0IX_SHLW_RES_ID  0x4801
0044 #define TELEM_APL_S0IX_DEEP_RES_ID  0x4802
0045 #define TELEM_APL_D0IX_ID       0x581A
0046 #define TELEM_APL_D3_ID         0x5819
0047 #define TELEM_APL_PG_ID         0x5818
0048 
0049 #define TELEM_INFO_SRAMEVTS_MASK    0xFF00
0050 #define TELEM_INFO_SRAMEVTS_SHIFT   0x8
0051 #define TELEM_SSRAM_READ_TIMEOUT    10
0052 
0053 #define TELEM_MASK_BIT          1
0054 #define TELEM_MASK_BYTE         0xFF
0055 #define BYTES_PER_LONG          8
0056 #define TELEM_APL_MASK_PCS_STATE    0xF
0057 
0058 /* Max events in bitmap to check for */
0059 #define TELEM_PSS_IDLE_EVTS     25
0060 #define TELEM_PSS_IDLE_BLOCKED_EVTS 20
0061 #define TELEM_PSS_S0IX_BLOCKED_EVTS 20
0062 #define TELEM_PSS_S0IX_WAKEUP_EVTS  20
0063 #define TELEM_PSS_LTR_BLOCKING_EVTS 20
0064 #define TELEM_IOSS_DX_D0IX_EVTS     25
0065 #define TELEM_IOSS_PG_EVTS      30
0066 
0067 #define TELEM_CHECK_AND_PARSE_EVTS(EVTID, EVTNUM, BUF, EVTLOG, EVTDAT, MASK) { \
0068     if (evtlog[index].telem_evtid == (EVTID)) { \
0069         for (idx = 0; idx < (EVTNUM); idx++) \
0070             (BUF)[idx] = ((EVTLOG) >> (EVTDAT)[idx].bit_pos) & \
0071                      (MASK); \
0072     continue; \
0073     } \
0074 }
0075 
0076 #define TELEM_CHECK_AND_PARSE_CTRS(EVTID, CTR) { \
0077     if (evtlog[index].telem_evtid == (EVTID)) { \
0078         (CTR) = evtlog[index].telem_evtlog; \
0079         continue; \
0080     } \
0081 }
0082 
0083 static u8 suspend_prep_ok;
0084 static u32 suspend_shlw_ctr_temp, suspend_deep_ctr_temp;
0085 static u64 suspend_shlw_res_temp, suspend_deep_res_temp;
0086 
0087 struct telemetry_susp_stats {
0088     u32 shlw_ctr;
0089     u32 deep_ctr;
0090     u64 shlw_res;
0091     u64 deep_res;
0092 };
0093 
0094 /* Bitmap definitions for default counters in APL */
0095 struct telem_pss_idle_stateinfo {
0096     const char *name;
0097     u32 bit_pos;
0098 };
0099 
0100 static struct telem_pss_idle_stateinfo telem_apl_pss_idle_data[] = {
0101     {"IA_CORE0_C1E",        0},
0102     {"IA_CORE1_C1E",        1},
0103     {"IA_CORE2_C1E",        2},
0104     {"IA_CORE3_C1E",        3},
0105     {"IA_CORE0_C6",         16},
0106     {"IA_CORE1_C6",         17},
0107     {"IA_CORE2_C6",         18},
0108     {"IA_CORE3_C6",         19},
0109     {"IA_MODULE0_C7",       32},
0110     {"IA_MODULE1_C7",       33},
0111     {"GT_RC6",          40},
0112     {"IUNIT_PROCESSING_IDLE",   41},
0113     {"FAR_MEM_IDLE",        43},
0114     {"DISPLAY_IDLE",        44},
0115     {"IUNIT_INPUT_SYSTEM_IDLE", 45},
0116     {"PCS_STATUS",          60},
0117 };
0118 
0119 struct telem_pcs_blkd_info {
0120     const char *name;
0121     u32 bit_pos;
0122 };
0123 
0124 static struct telem_pcs_blkd_info telem_apl_pcs_idle_blkd_data[] = {
0125     {"COMPUTE",         0},
0126     {"MISC",            8},
0127     {"MODULE_ACTIONS_PENDING",  16},
0128     {"LTR",             24},
0129     {"DISPLAY_WAKE",        32},
0130     {"ISP_WAKE",            40},
0131     {"PSF0_ACTIVE",         48},
0132 };
0133 
0134 static struct telem_pcs_blkd_info telem_apl_pcs_s0ix_blkd_data[] = {
0135     {"LTR",             0},
0136     {"IRTL",            8},
0137     {"WAKE_DEADLINE_PENDING",   16},
0138     {"DISPLAY",         24},
0139     {"ISP",             32},
0140     {"CORE",            40},
0141     {"PMC",             48},
0142     {"MISC",            56},
0143 };
0144 
0145 struct telem_pss_ltr_info {
0146     const char *name;
0147     u32 bit_pos;
0148 };
0149 
0150 static struct telem_pss_ltr_info telem_apl_pss_ltr_data[] = {
0151     {"CORE_ACTIVE",     0},
0152     {"MEM_UP",      8},
0153     {"DFX",         16},
0154     {"DFX_FORCE_LTR",   24},
0155     {"DISPLAY",     32},
0156     {"ISP",         40},
0157     {"SOUTH",       48},
0158 };
0159 
0160 struct telem_pss_wakeup_info {
0161     const char *name;
0162     u32 bit_pos;
0163 };
0164 
0165 static struct telem_pss_wakeup_info telem_apl_pss_wakeup[] = {
0166     {"IP_IDLE",         0},
0167     {"DISPLAY_WAKE",        8},
0168     {"VOLTAGE_REG_INT",     16},
0169     {"DROWSY_TIMER (HOTPLUG)",  24},
0170     {"CORE_WAKE",           32},
0171     {"MISC_S0IX",           40},
0172     {"MISC_ABORT",          56},
0173 };
0174 
0175 struct telem_ioss_d0ix_stateinfo {
0176     const char *name;
0177     u32 bit_pos;
0178 };
0179 
0180 static struct telem_ioss_d0ix_stateinfo telem_apl_ioss_d0ix_data[] = {
0181     {"CSE",     0},
0182     {"SCC2",    1},
0183     {"GMM",     2},
0184     {"XDCI",    3},
0185     {"XHCI",    4},
0186     {"ISH",     5},
0187     {"AVS",     6},
0188     {"PCIE0P1", 7},
0189     {"PECI0P0", 8},
0190     {"LPSS",    9},
0191     {"SCC",     10},
0192     {"PWM",     11},
0193     {"PCIE1_P3",    12},
0194     {"PCIE1_P2",    13},
0195     {"PCIE1_P1",    14},
0196     {"PCIE1_P0",    15},
0197     {"CNV",     16},
0198     {"SATA",    17},
0199     {"PRTC",    18},
0200 };
0201 
0202 struct telem_ioss_pg_info {
0203     const char *name;
0204     u32 bit_pos;
0205 };
0206 
0207 static struct telem_ioss_pg_info telem_apl_ioss_pg_data[] = {
0208     {"LPSS",    0},
0209     {"SCC",     1},
0210     {"P2SB",    2},
0211     {"SCC2",    3},
0212     {"GMM",     4},
0213     {"PCIE0",   5},
0214     {"XDCI",    6},
0215     {"xHCI",    7},
0216     {"CSE",     8},
0217     {"SPI",     9},
0218     {"AVSPGD4", 10},
0219     {"AVSPGD3", 11},
0220     {"AVSPGD2", 12},
0221     {"AVSPGD1", 13},
0222     {"ISH",     14},
0223     {"EXI",     15},
0224     {"NPKVRC",  16},
0225     {"NPKVNN",  17},
0226     {"CUNIT",   18},
0227     {"FUSE_CTRL",   19},
0228     {"PCIE1",   20},
0229     {"CNV",     21},
0230     {"LPC",     22},
0231     {"SATA",    23},
0232     {"SMB",     24},
0233     {"PRTC",    25},
0234 };
0235 
0236 struct telemetry_debugfs_conf {
0237     struct telemetry_susp_stats suspend_stats;
0238     struct dentry *telemetry_dbg_dir;
0239 
0240     /* Bitmap Data */
0241     struct telem_ioss_d0ix_stateinfo *ioss_d0ix_data;
0242     struct telem_pss_idle_stateinfo *pss_idle_data;
0243     struct telem_pcs_blkd_info *pcs_idle_blkd_data;
0244     struct telem_pcs_blkd_info *pcs_s0ix_blkd_data;
0245     struct telem_pss_wakeup_info *pss_wakeup;
0246     struct telem_pss_ltr_info *pss_ltr_data;
0247     struct telem_ioss_pg_info *ioss_pg_data;
0248     u8 pcs_idle_blkd_evts;
0249     u8 pcs_s0ix_blkd_evts;
0250     u8 pss_wakeup_evts;
0251     u8 pss_idle_evts;
0252     u8 pss_ltr_evts;
0253     u8 ioss_d0ix_evts;
0254     u8 ioss_pg_evts;
0255 
0256     /* IDs */
0257     u16  pss_ltr_blocking_id;
0258     u16  pcs_idle_blkd_id;
0259     u16  pcs_s0ix_blkd_id;
0260     u16  s0ix_total_occ_id;
0261     u16  s0ix_shlw_occ_id;
0262     u16  s0ix_deep_occ_id;
0263     u16  s0ix_total_res_id;
0264     u16  s0ix_shlw_res_id;
0265     u16  s0ix_deep_res_id;
0266     u16  pss_wakeup_id;
0267     u16  ioss_d0ix_id;
0268     u16  pstates_id;
0269     u16  pss_idle_id;
0270     u16  ioss_d3_id;
0271     u16  ioss_pg_id;
0272 };
0273 
0274 static struct telemetry_debugfs_conf *debugfs_conf;
0275 
0276 static struct telemetry_debugfs_conf telem_apl_debugfs_conf = {
0277     .pss_idle_data = telem_apl_pss_idle_data,
0278     .pcs_idle_blkd_data = telem_apl_pcs_idle_blkd_data,
0279     .pcs_s0ix_blkd_data = telem_apl_pcs_s0ix_blkd_data,
0280     .pss_ltr_data = telem_apl_pss_ltr_data,
0281     .pss_wakeup = telem_apl_pss_wakeup,
0282     .ioss_d0ix_data = telem_apl_ioss_d0ix_data,
0283     .ioss_pg_data = telem_apl_ioss_pg_data,
0284 
0285     .pss_idle_evts = ARRAY_SIZE(telem_apl_pss_idle_data),
0286     .pcs_idle_blkd_evts = ARRAY_SIZE(telem_apl_pcs_idle_blkd_data),
0287     .pcs_s0ix_blkd_evts = ARRAY_SIZE(telem_apl_pcs_s0ix_blkd_data),
0288     .pss_ltr_evts = ARRAY_SIZE(telem_apl_pss_ltr_data),
0289     .pss_wakeup_evts = ARRAY_SIZE(telem_apl_pss_wakeup),
0290     .ioss_d0ix_evts = ARRAY_SIZE(telem_apl_ioss_d0ix_data),
0291     .ioss_pg_evts = ARRAY_SIZE(telem_apl_ioss_pg_data),
0292 
0293     .pstates_id = TELEM_APL_PSS_PSTATES_ID,
0294     .pss_idle_id = TELEM_APL_PSS_IDLE_ID,
0295     .pcs_idle_blkd_id = TELEM_APL_PCS_IDLE_BLOCKED_ID,
0296     .pcs_s0ix_blkd_id = TELEM_APL_PCS_S0IX_BLOCKED_ID,
0297     .pss_wakeup_id = TELEM_APL_PSS_WAKEUP_ID,
0298     .pss_ltr_blocking_id = TELEM_APL_PSS_LTR_BLOCKING_ID,
0299     .s0ix_total_occ_id = TELEM_APL_S0IX_TOTAL_OCC_ID,
0300     .s0ix_shlw_occ_id = TELEM_APL_S0IX_SHLW_OCC_ID,
0301     .s0ix_deep_occ_id = TELEM_APL_S0IX_DEEP_OCC_ID,
0302     .s0ix_total_res_id = TELEM_APL_S0IX_TOTAL_RES_ID,
0303     .s0ix_shlw_res_id = TELEM_APL_S0IX_SHLW_RES_ID,
0304     .s0ix_deep_res_id = TELEM_APL_S0IX_DEEP_RES_ID,
0305     .ioss_d0ix_id = TELEM_APL_D0IX_ID,
0306     .ioss_d3_id = TELEM_APL_D3_ID,
0307     .ioss_pg_id = TELEM_APL_PG_ID,
0308 };
0309 
0310 static const struct x86_cpu_id telemetry_debugfs_cpu_ids[] = {
0311     X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT,   &telem_apl_debugfs_conf),
0312     X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_PLUS,  &telem_apl_debugfs_conf),
0313     {}
0314 };
0315 MODULE_DEVICE_TABLE(x86cpu, telemetry_debugfs_cpu_ids);
0316 
0317 static int telemetry_debugfs_check_evts(void)
0318 {
0319     if ((debugfs_conf->pss_idle_evts > TELEM_PSS_IDLE_EVTS) ||
0320         (debugfs_conf->pcs_idle_blkd_evts > TELEM_PSS_IDLE_BLOCKED_EVTS) ||
0321         (debugfs_conf->pcs_s0ix_blkd_evts > TELEM_PSS_S0IX_BLOCKED_EVTS) ||
0322         (debugfs_conf->pss_ltr_evts > TELEM_PSS_LTR_BLOCKING_EVTS) ||
0323         (debugfs_conf->pss_wakeup_evts > TELEM_PSS_S0IX_WAKEUP_EVTS) ||
0324         (debugfs_conf->ioss_d0ix_evts > TELEM_IOSS_DX_D0IX_EVTS) ||
0325         (debugfs_conf->ioss_pg_evts > TELEM_IOSS_PG_EVTS))
0326         return -EINVAL;
0327 
0328     return 0;
0329 }
0330 
0331 static int telem_pss_states_show(struct seq_file *s, void *unused)
0332 {
0333     struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
0334     struct telemetry_debugfs_conf *conf = debugfs_conf;
0335     const char *name[TELEM_MAX_OS_ALLOCATED_EVENTS];
0336     u32 pcs_idle_blkd[TELEM_PSS_IDLE_BLOCKED_EVTS],
0337         pcs_s0ix_blkd[TELEM_PSS_S0IX_BLOCKED_EVTS],
0338         pss_s0ix_wakeup[TELEM_PSS_S0IX_WAKEUP_EVTS],
0339         pss_ltr_blkd[TELEM_PSS_LTR_BLOCKING_EVTS],
0340         pss_idle[TELEM_PSS_IDLE_EVTS];
0341     int index, idx, ret, err = 0;
0342     u64 pstates = 0;
0343 
0344     ret = telemetry_read_eventlog(TELEM_PSS, evtlog,
0345                       TELEM_MAX_OS_ALLOCATED_EVENTS);
0346     if (ret < 0)
0347         return ret;
0348 
0349     err = telemetry_get_evtname(TELEM_PSS, name,
0350                     TELEM_MAX_OS_ALLOCATED_EVENTS);
0351     if (err < 0)
0352         return err;
0353 
0354     seq_puts(s, "\n----------------------------------------------------\n");
0355     seq_puts(s, "\tPSS TELEM EVENTLOG (Residency = field/19.2 us\n");
0356     seq_puts(s, "----------------------------------------------------\n");
0357     for (index = 0; index < ret; index++) {
0358         seq_printf(s, "%-32s %llu\n",
0359                name[index], evtlog[index].telem_evtlog);
0360 
0361         /* Fetch PSS IDLE State */
0362         if (evtlog[index].telem_evtid == conf->pss_idle_id) {
0363             pss_idle[conf->pss_idle_evts - 1] =
0364             (evtlog[index].telem_evtlog >>
0365             conf->pss_idle_data[conf->pss_idle_evts - 1].bit_pos) &
0366             TELEM_APL_MASK_PCS_STATE;
0367         }
0368 
0369         TELEM_CHECK_AND_PARSE_EVTS(conf->pss_idle_id,
0370                        conf->pss_idle_evts - 1,
0371                        pss_idle, evtlog[index].telem_evtlog,
0372                        conf->pss_idle_data, TELEM_MASK_BIT);
0373 
0374         TELEM_CHECK_AND_PARSE_EVTS(conf->pcs_idle_blkd_id,
0375                        conf->pcs_idle_blkd_evts,
0376                        pcs_idle_blkd,
0377                        evtlog[index].telem_evtlog,
0378                        conf->pcs_idle_blkd_data,
0379                        TELEM_MASK_BYTE);
0380 
0381         TELEM_CHECK_AND_PARSE_EVTS(conf->pcs_s0ix_blkd_id,
0382                        conf->pcs_s0ix_blkd_evts,
0383                        pcs_s0ix_blkd,
0384                        evtlog[index].telem_evtlog,
0385                        conf->pcs_s0ix_blkd_data,
0386                        TELEM_MASK_BYTE);
0387 
0388         TELEM_CHECK_AND_PARSE_EVTS(conf->pss_wakeup_id,
0389                        conf->pss_wakeup_evts,
0390                        pss_s0ix_wakeup,
0391                        evtlog[index].telem_evtlog,
0392                        conf->pss_wakeup, TELEM_MASK_BYTE);
0393 
0394         TELEM_CHECK_AND_PARSE_EVTS(conf->pss_ltr_blocking_id,
0395                        conf->pss_ltr_evts, pss_ltr_blkd,
0396                        evtlog[index].telem_evtlog,
0397                        conf->pss_ltr_data, TELEM_MASK_BYTE);
0398 
0399         if (evtlog[index].telem_evtid == debugfs_conf->pstates_id)
0400             pstates = evtlog[index].telem_evtlog;
0401     }
0402 
0403     seq_puts(s, "\n--------------------------------------\n");
0404     seq_puts(s, "PStates\n");
0405     seq_puts(s, "--------------------------------------\n");
0406     seq_puts(s, "Domain\t\t\t\tFreq(Mhz)\n");
0407     seq_printf(s, " IA\t\t\t\t %llu\n GT\t\t\t\t %llu\n",
0408            (pstates & TELEM_MASK_BYTE)*100,
0409            ((pstates >> 8) & TELEM_MASK_BYTE)*50/3);
0410 
0411     seq_printf(s, " IUNIT\t\t\t\t %llu\n SA\t\t\t\t %llu\n",
0412            ((pstates >> 16) & TELEM_MASK_BYTE)*25,
0413            ((pstates >> 24) & TELEM_MASK_BYTE)*50/3);
0414 
0415     seq_puts(s, "\n--------------------------------------\n");
0416     seq_puts(s, "PSS IDLE Status\n");
0417     seq_puts(s, "--------------------------------------\n");
0418     seq_puts(s, "Device\t\t\t\t\tIDLE\n");
0419     for (index = 0; index < debugfs_conf->pss_idle_evts; index++) {
0420         seq_printf(s, "%-32s\t%u\n",
0421                debugfs_conf->pss_idle_data[index].name,
0422                pss_idle[index]);
0423     }
0424 
0425     seq_puts(s, "\n--------------------------------------\n");
0426     seq_puts(s, "PSS Idle blkd Status (~1ms saturating bucket)\n");
0427     seq_puts(s, "--------------------------------------\n");
0428     seq_puts(s, "Blocker\t\t\t\t\tCount\n");
0429     for (index = 0; index < debugfs_conf->pcs_idle_blkd_evts; index++) {
0430         seq_printf(s, "%-32s\t%u\n",
0431                debugfs_conf->pcs_idle_blkd_data[index].name,
0432                pcs_idle_blkd[index]);
0433     }
0434 
0435     seq_puts(s, "\n--------------------------------------\n");
0436     seq_puts(s, "PSS S0ix blkd Status (~1ms saturating bucket)\n");
0437     seq_puts(s, "--------------------------------------\n");
0438     seq_puts(s, "Blocker\t\t\t\t\tCount\n");
0439     for (index = 0; index < debugfs_conf->pcs_s0ix_blkd_evts; index++) {
0440         seq_printf(s, "%-32s\t%u\n",
0441                debugfs_conf->pcs_s0ix_blkd_data[index].name,
0442                pcs_s0ix_blkd[index]);
0443     }
0444 
0445     seq_puts(s, "\n--------------------------------------\n");
0446     seq_puts(s, "LTR Blocking Status (~1ms saturating bucket)\n");
0447     seq_puts(s, "--------------------------------------\n");
0448     seq_puts(s, "Blocker\t\t\t\t\tCount\n");
0449     for (index = 0; index < debugfs_conf->pss_ltr_evts; index++) {
0450         seq_printf(s, "%-32s\t%u\n",
0451                debugfs_conf->pss_ltr_data[index].name,
0452                pss_s0ix_wakeup[index]);
0453     }
0454 
0455     seq_puts(s, "\n--------------------------------------\n");
0456     seq_puts(s, "Wakes Status (~1ms saturating bucket)\n");
0457     seq_puts(s, "--------------------------------------\n");
0458     seq_puts(s, "Wakes\t\t\t\t\tCount\n");
0459     for (index = 0; index < debugfs_conf->pss_wakeup_evts; index++) {
0460         seq_printf(s, "%-32s\t%u\n",
0461                debugfs_conf->pss_wakeup[index].name,
0462                pss_ltr_blkd[index]);
0463     }
0464 
0465     return 0;
0466 }
0467 
0468 DEFINE_SHOW_ATTRIBUTE(telem_pss_states);
0469 
0470 static int telem_ioss_states_show(struct seq_file *s, void *unused)
0471 {
0472     struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
0473     const char *name[TELEM_MAX_OS_ALLOCATED_EVENTS];
0474     int index, ret, err;
0475 
0476     ret = telemetry_read_eventlog(TELEM_IOSS, evtlog,
0477                       TELEM_MAX_OS_ALLOCATED_EVENTS);
0478     if (ret < 0)
0479         return ret;
0480 
0481     err = telemetry_get_evtname(TELEM_IOSS, name,
0482                     TELEM_MAX_OS_ALLOCATED_EVENTS);
0483     if (err < 0)
0484         return err;
0485 
0486     seq_puts(s, "--------------------------------------\n");
0487     seq_puts(s, "\tI0SS TELEMETRY EVENTLOG\n");
0488     seq_puts(s, "--------------------------------------\n");
0489     for (index = 0; index < ret; index++) {
0490         seq_printf(s, "%-32s 0x%llx\n",
0491                name[index], evtlog[index].telem_evtlog);
0492     }
0493 
0494     return 0;
0495 }
0496 
0497 DEFINE_SHOW_ATTRIBUTE(telem_ioss_states);
0498 
0499 static int telem_soc_states_show(struct seq_file *s, void *unused)
0500 {
0501     u32 d3_sts[TELEM_IOSS_DX_D0IX_EVTS], d0ix_sts[TELEM_IOSS_DX_D0IX_EVTS];
0502     u32 pg_sts[TELEM_IOSS_PG_EVTS], pss_idle[TELEM_PSS_IDLE_EVTS];
0503     struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
0504     u32 s0ix_total_ctr = 0, s0ix_shlw_ctr = 0, s0ix_deep_ctr = 0;
0505     u64 s0ix_total_res = 0, s0ix_shlw_res = 0, s0ix_deep_res = 0;
0506     struct telemetry_debugfs_conf *conf = debugfs_conf;
0507     struct pci_dev *dev = NULL;
0508     int index, idx, ret;
0509     u32 d3_state;
0510     u16 pmcsr;
0511 
0512     ret = telemetry_read_eventlog(TELEM_IOSS, evtlog,
0513                       TELEM_MAX_OS_ALLOCATED_EVENTS);
0514     if (ret < 0)
0515         return ret;
0516 
0517     for (index = 0; index < ret; index++) {
0518         TELEM_CHECK_AND_PARSE_EVTS(conf->ioss_d3_id,
0519                        conf->ioss_d0ix_evts,
0520                        d3_sts, evtlog[index].telem_evtlog,
0521                        conf->ioss_d0ix_data,
0522                        TELEM_MASK_BIT);
0523 
0524         TELEM_CHECK_AND_PARSE_EVTS(conf->ioss_pg_id, conf->ioss_pg_evts,
0525                        pg_sts, evtlog[index].telem_evtlog,
0526                        conf->ioss_pg_data, TELEM_MASK_BIT);
0527 
0528         TELEM_CHECK_AND_PARSE_EVTS(conf->ioss_d0ix_id,
0529                        conf->ioss_d0ix_evts,
0530                        d0ix_sts, evtlog[index].telem_evtlog,
0531                        conf->ioss_d0ix_data,
0532                        TELEM_MASK_BIT);
0533 
0534         TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_total_occ_id,
0535                        s0ix_total_ctr);
0536 
0537         TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_occ_id,
0538                        s0ix_shlw_ctr);
0539 
0540         TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_occ_id,
0541                        s0ix_deep_ctr);
0542 
0543         TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_total_res_id,
0544                        s0ix_total_res);
0545 
0546         TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_res_id,
0547                        s0ix_shlw_res);
0548 
0549         TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_res_id,
0550                        s0ix_deep_res);
0551     }
0552 
0553     seq_puts(s, "\n---------------------------------------------------\n");
0554     seq_puts(s, "S0IX Type\t\t\t Occurrence\t\t Residency(us)\n");
0555     seq_puts(s, "---------------------------------------------------\n");
0556 
0557     seq_printf(s, "S0IX Shallow\t\t\t %10u\t %10llu\n",
0558            s0ix_shlw_ctr -
0559            conf->suspend_stats.shlw_ctr,
0560            (u64)((s0ix_shlw_res -
0561            conf->suspend_stats.shlw_res)*10/192));
0562 
0563     seq_printf(s, "S0IX Deep\t\t\t %10u\t %10llu\n",
0564            s0ix_deep_ctr -
0565            conf->suspend_stats.deep_ctr,
0566            (u64)((s0ix_deep_res -
0567            conf->suspend_stats.deep_res)*10/192));
0568 
0569     seq_printf(s, "Suspend(With S0ixShallow)\t %10u\t %10llu\n",
0570            conf->suspend_stats.shlw_ctr,
0571            (u64)(conf->suspend_stats.shlw_res*10)/192);
0572 
0573     seq_printf(s, "Suspend(With S0ixDeep)\t\t %10u\t %10llu\n",
0574            conf->suspend_stats.deep_ctr,
0575            (u64)(conf->suspend_stats.deep_res*10)/192);
0576 
0577     seq_printf(s, "TOTAL S0IX\t\t\t %10u\t %10llu\n", s0ix_total_ctr,
0578            (u64)(s0ix_total_res*10/192));
0579     seq_puts(s, "\n-------------------------------------------------\n");
0580     seq_puts(s, "\t\tDEVICE STATES\n");
0581     seq_puts(s, "-------------------------------------------------\n");
0582 
0583     for_each_pci_dev(dev) {
0584         pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
0585         d3_state = ((pmcsr & PCI_PM_CTRL_STATE_MASK) ==
0586                 (__force int)PCI_D3hot) ? 1 : 0;
0587 
0588         seq_printf(s, "pci %04x %04X %s %20.20s: ",
0589                dev->vendor, dev->device, dev_name(&dev->dev),
0590                dev_driver_string(&dev->dev));
0591         seq_printf(s, " d3:%x\n", d3_state);
0592     }
0593 
0594     seq_puts(s, "\n--------------------------------------\n");
0595     seq_puts(s, "D3/D0i3 Status\n");
0596     seq_puts(s, "--------------------------------------\n");
0597     seq_puts(s, "Block\t\t D3\t D0i3\n");
0598     for (index = 0; index < conf->ioss_d0ix_evts; index++) {
0599         seq_printf(s, "%-10s\t %u\t %u\n",
0600                conf->ioss_d0ix_data[index].name,
0601                d3_sts[index], d0ix_sts[index]);
0602     }
0603 
0604     seq_puts(s, "\n--------------------------------------\n");
0605     seq_puts(s, "South Complex PowerGate Status\n");
0606     seq_puts(s, "--------------------------------------\n");
0607     seq_puts(s, "Device\t\t PG\n");
0608     for (index = 0; index < conf->ioss_pg_evts; index++) {
0609         seq_printf(s, "%-10s\t %u\n",
0610                conf->ioss_pg_data[index].name,
0611                pg_sts[index]);
0612     }
0613 
0614     evtlog->telem_evtid = conf->pss_idle_id;
0615     ret = telemetry_read_events(TELEM_PSS, evtlog, 1);
0616     if (ret < 0)
0617         return ret;
0618 
0619     seq_puts(s, "\n-----------------------------------------\n");
0620     seq_puts(s, "North Idle Status\n");
0621     seq_puts(s, "-----------------------------------------\n");
0622     for (idx = 0; idx < conf->pss_idle_evts - 1; idx++) {
0623         pss_idle[idx] = (evtlog->telem_evtlog >>
0624                 conf->pss_idle_data[idx].bit_pos) &
0625                 TELEM_MASK_BIT;
0626     }
0627 
0628     pss_idle[idx] = (evtlog->telem_evtlog >>
0629             conf->pss_idle_data[idx].bit_pos) &
0630             TELEM_APL_MASK_PCS_STATE;
0631 
0632     for (index = 0; index < conf->pss_idle_evts; index++) {
0633         seq_printf(s, "%-30s %u\n",
0634                conf->pss_idle_data[index].name,
0635                pss_idle[index]);
0636     }
0637 
0638     seq_puts(s, "\nPCS_STATUS Code\n");
0639     seq_puts(s, "0:C0 1:C1 2:C1_DN_WT_DEV 3:C2 4:C2_WT_DE_MEM_UP\n");
0640     seq_puts(s, "5:C2_WT_DE_MEM_DOWN 6:C2_UP_WT_DEV 7:C2_DN 8:C2_VOA\n");
0641     seq_puts(s, "9:C2_VOA_UP 10:S0IX_PRE 11:S0IX\n");
0642 
0643     return 0;
0644 }
0645 
0646 DEFINE_SHOW_ATTRIBUTE(telem_soc_states);
0647 
0648 static int telem_s0ix_res_get(void *data, u64 *val)
0649 {
0650     struct telemetry_plt_config *plt_config = telemetry_get_pltdata();
0651     u64 s0ix_total_res;
0652     int ret;
0653 
0654     ret = intel_pmc_s0ix_counter_read(plt_config->pmc, &s0ix_total_res);
0655     if (ret) {
0656         pr_err("Failed to read S0ix residency");
0657         return ret;
0658     }
0659 
0660     *val = s0ix_total_res;
0661 
0662     return 0;
0663 }
0664 
0665 DEFINE_DEBUGFS_ATTRIBUTE(telem_s0ix_fops, telem_s0ix_res_get, NULL, "%llu\n");
0666 
0667 static int telem_pss_trc_verb_show(struct seq_file *s, void *unused)
0668 {
0669     u32 verbosity;
0670     int err;
0671 
0672     err = telemetry_get_trace_verbosity(TELEM_PSS, &verbosity);
0673     if (err) {
0674         pr_err("Get PSS Trace Verbosity Failed with Error %d\n", err);
0675         return -EFAULT;
0676     }
0677 
0678     seq_printf(s, "PSS Trace Verbosity %u\n", verbosity);
0679     return 0;
0680 }
0681 
0682 static ssize_t telem_pss_trc_verb_write(struct file *file,
0683                     const char __user *userbuf,
0684                     size_t count, loff_t *ppos)
0685 {
0686     u32 verbosity;
0687     int err;
0688 
0689     err = kstrtou32_from_user(userbuf, count, 0, &verbosity);
0690     if (err)
0691         return err;
0692 
0693     err = telemetry_set_trace_verbosity(TELEM_PSS, verbosity);
0694     if (err) {
0695         pr_err("Changing PSS Trace Verbosity Failed. Error %d\n", err);
0696         return err;
0697     }
0698 
0699     return count;
0700 }
0701 
0702 static int telem_pss_trc_verb_open(struct inode *inode, struct file *file)
0703 {
0704     return single_open(file, telem_pss_trc_verb_show, inode->i_private);
0705 }
0706 
0707 static const struct file_operations telem_pss_trc_verb_ops = {
0708     .open       = telem_pss_trc_verb_open,
0709     .read       = seq_read,
0710     .write      = telem_pss_trc_verb_write,
0711     .llseek     = seq_lseek,
0712     .release    = single_release,
0713 };
0714 
0715 static int telem_ioss_trc_verb_show(struct seq_file *s, void *unused)
0716 {
0717     u32 verbosity;
0718     int err;
0719 
0720     err = telemetry_get_trace_verbosity(TELEM_IOSS, &verbosity);
0721     if (err) {
0722         pr_err("Get IOSS Trace Verbosity Failed with Error %d\n", err);
0723         return -EFAULT;
0724     }
0725 
0726     seq_printf(s, "IOSS Trace Verbosity %u\n", verbosity);
0727     return 0;
0728 }
0729 
0730 static ssize_t telem_ioss_trc_verb_write(struct file *file,
0731                      const char __user *userbuf,
0732                      size_t count, loff_t *ppos)
0733 {
0734     u32 verbosity;
0735     int err;
0736 
0737     err = kstrtou32_from_user(userbuf, count, 0, &verbosity);
0738     if (err)
0739         return err;
0740 
0741     err = telemetry_set_trace_verbosity(TELEM_IOSS, verbosity);
0742     if (err) {
0743         pr_err("Changing IOSS Trace Verbosity Failed. Error %d\n", err);
0744         return err;
0745     }
0746 
0747     return count;
0748 }
0749 
0750 static int telem_ioss_trc_verb_open(struct inode *inode, struct file *file)
0751 {
0752     return single_open(file, telem_ioss_trc_verb_show, inode->i_private);
0753 }
0754 
0755 static const struct file_operations telem_ioss_trc_verb_ops = {
0756     .open       = telem_ioss_trc_verb_open,
0757     .read       = seq_read,
0758     .write      = telem_ioss_trc_verb_write,
0759     .llseek     = seq_lseek,
0760     .release    = single_release,
0761 };
0762 
0763 static int pm_suspend_prep_cb(void)
0764 {
0765     struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
0766     struct telemetry_debugfs_conf *conf = debugfs_conf;
0767     int ret, index;
0768 
0769     ret = telemetry_raw_read_eventlog(TELEM_IOSS, evtlog,
0770             TELEM_MAX_OS_ALLOCATED_EVENTS);
0771     if (ret < 0) {
0772         suspend_prep_ok = 0;
0773         goto out;
0774     }
0775 
0776     for (index = 0; index < ret; index++) {
0777 
0778         TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_occ_id,
0779                        suspend_shlw_ctr_temp);
0780 
0781         TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_occ_id,
0782                        suspend_deep_ctr_temp);
0783 
0784         TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_res_id,
0785                        suspend_shlw_res_temp);
0786 
0787         TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_res_id,
0788                        suspend_deep_res_temp);
0789     }
0790     suspend_prep_ok = 1;
0791 out:
0792     return NOTIFY_OK;
0793 }
0794 
0795 static int pm_suspend_exit_cb(void)
0796 {
0797     struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
0798     static u32 suspend_shlw_ctr_exit, suspend_deep_ctr_exit;
0799     static u64 suspend_shlw_res_exit, suspend_deep_res_exit;
0800     struct telemetry_debugfs_conf *conf = debugfs_conf;
0801     int ret, index;
0802 
0803     if (!suspend_prep_ok)
0804         goto out;
0805 
0806     ret = telemetry_raw_read_eventlog(TELEM_IOSS, evtlog,
0807                       TELEM_MAX_OS_ALLOCATED_EVENTS);
0808     if (ret < 0)
0809         goto out;
0810 
0811     for (index = 0; index < ret; index++) {
0812         TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_occ_id,
0813                        suspend_shlw_ctr_exit);
0814 
0815         TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_occ_id,
0816                        suspend_deep_ctr_exit);
0817 
0818         TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_res_id,
0819                        suspend_shlw_res_exit);
0820 
0821         TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_res_id,
0822                        suspend_deep_res_exit);
0823     }
0824 
0825     if ((suspend_shlw_ctr_exit < suspend_shlw_ctr_temp) ||
0826         (suspend_deep_ctr_exit < suspend_deep_ctr_temp) ||
0827         (suspend_shlw_res_exit < suspend_shlw_res_temp) ||
0828         (suspend_deep_res_exit < suspend_deep_res_temp)) {
0829         pr_err("Wrong s0ix counters detected\n");
0830         goto out;
0831     }
0832 
0833     /*
0834      * Due to some design limitations in the firmware, sometimes the
0835      * counters do not get updated by the time we reach here. As a
0836      * workaround, we try to see if this was a genuine case of sleep
0837      * failure or not by cross-checking from PMC GCR registers directly.
0838      */
0839     if (suspend_shlw_ctr_exit == suspend_shlw_ctr_temp &&
0840         suspend_deep_ctr_exit == suspend_deep_ctr_temp) {
0841         struct telemetry_plt_config *plt_config = telemetry_get_pltdata();
0842         struct intel_pmc_dev *pmc = plt_config->pmc;
0843 
0844         ret = intel_pmc_gcr_read64(pmc, PMC_GCR_TELEM_SHLW_S0IX_REG,
0845                       &suspend_shlw_res_exit);
0846         if (ret < 0)
0847             goto out;
0848 
0849         ret = intel_pmc_gcr_read64(pmc, PMC_GCR_TELEM_DEEP_S0IX_REG,
0850                       &suspend_deep_res_exit);
0851         if (ret < 0)
0852             goto out;
0853 
0854         if (suspend_shlw_res_exit > suspend_shlw_res_temp)
0855             suspend_shlw_ctr_exit++;
0856 
0857         if (suspend_deep_res_exit > suspend_deep_res_temp)
0858             suspend_deep_ctr_exit++;
0859     }
0860 
0861     suspend_shlw_ctr_exit -= suspend_shlw_ctr_temp;
0862     suspend_deep_ctr_exit -= suspend_deep_ctr_temp;
0863     suspend_shlw_res_exit -= suspend_shlw_res_temp;
0864     suspend_deep_res_exit -= suspend_deep_res_temp;
0865 
0866     if (suspend_shlw_ctr_exit != 0) {
0867         conf->suspend_stats.shlw_ctr +=
0868         suspend_shlw_ctr_exit;
0869 
0870         conf->suspend_stats.shlw_res +=
0871         suspend_shlw_res_exit;
0872     }
0873 
0874     if (suspend_deep_ctr_exit != 0) {
0875         conf->suspend_stats.deep_ctr +=
0876         suspend_deep_ctr_exit;
0877 
0878         conf->suspend_stats.deep_res +=
0879         suspend_deep_res_exit;
0880     }
0881 
0882 out:
0883     suspend_prep_ok = 0;
0884     return NOTIFY_OK;
0885 }
0886 
0887 static int pm_notification(struct notifier_block *this,
0888                unsigned long event, void *ptr)
0889 {
0890     switch (event) {
0891     case PM_SUSPEND_PREPARE:
0892         return pm_suspend_prep_cb();
0893     case PM_POST_SUSPEND:
0894         return pm_suspend_exit_cb();
0895     }
0896 
0897     return NOTIFY_DONE;
0898 }
0899 
0900 static struct notifier_block pm_notifier = {
0901     .notifier_call = pm_notification,
0902 };
0903 
0904 static int __init telemetry_debugfs_init(void)
0905 {
0906     const struct x86_cpu_id *id;
0907     int err;
0908     struct dentry *dir;
0909 
0910     /* Only APL supported for now */
0911     id = x86_match_cpu(telemetry_debugfs_cpu_ids);
0912     if (!id)
0913         return -ENODEV;
0914 
0915     debugfs_conf = (struct telemetry_debugfs_conf *)id->driver_data;
0916 
0917     if (!telemetry_get_pltdata()) {
0918         pr_info("Invalid pltconfig, ensure IPC1 device is enabled in BIOS\n");
0919         return -ENODEV;
0920     }
0921 
0922     err = telemetry_debugfs_check_evts();
0923     if (err < 0) {
0924         pr_info("telemetry_debugfs_check_evts failed\n");
0925         return -EINVAL;
0926     }
0927 
0928     register_pm_notifier(&pm_notifier);
0929 
0930     dir = debugfs_create_dir("telemetry", NULL);
0931     debugfs_conf->telemetry_dbg_dir = dir;
0932 
0933     debugfs_create_file("pss_info", S_IFREG | S_IRUGO, dir, NULL,
0934                 &telem_pss_states_fops);
0935     debugfs_create_file("ioss_info", S_IFREG | S_IRUGO, dir, NULL,
0936                 &telem_ioss_states_fops);
0937     debugfs_create_file("soc_states", S_IFREG | S_IRUGO, dir, NULL,
0938                 &telem_soc_states_fops);
0939     debugfs_create_file("s0ix_residency_usec", S_IFREG | S_IRUGO, dir, NULL,
0940                 &telem_s0ix_fops);
0941     debugfs_create_file("pss_trace_verbosity", S_IFREG | S_IRUGO, dir, NULL,
0942                 &telem_pss_trc_verb_ops);
0943     debugfs_create_file("ioss_trace_verbosity", S_IFREG | S_IRUGO, dir,
0944                 NULL, &telem_ioss_trc_verb_ops);
0945     return 0;
0946 }
0947 
0948 static void __exit telemetry_debugfs_exit(void)
0949 {
0950     debugfs_remove_recursive(debugfs_conf->telemetry_dbg_dir);
0951     debugfs_conf->telemetry_dbg_dir = NULL;
0952     unregister_pm_notifier(&pm_notifier);
0953 }
0954 
0955 late_initcall(telemetry_debugfs_init);
0956 module_exit(telemetry_debugfs_exit);
0957 
0958 MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
0959 MODULE_DESCRIPTION("Intel SoC Telemetry debugfs Interface");
0960 MODULE_VERSION(DRIVER_VERSION);
0961 MODULE_LICENSE("GPL v2");