cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

debugfs.c (27488B)


      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/mfd/intel_pmc_bxt.h>
     19#include <linux/module.h>
     20#include <linux/pci.h>
     21#include <linux/seq_file.h>
     22#include <linux/suspend.h>
     23
     24#include <asm/cpu_device_id.h>
     25#include <asm/intel-family.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
     83static u8 suspend_prep_ok;
     84static u32 suspend_shlw_ctr_temp, suspend_deep_ctr_temp;
     85static u64 suspend_shlw_res_temp, suspend_deep_res_temp;
     86
     87struct 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 */
     95struct telem_pss_idle_stateinfo {
     96	const char *name;
     97	u32 bit_pos;
     98};
     99
    100static 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
    119struct telem_pcs_blkd_info {
    120	const char *name;
    121	u32 bit_pos;
    122};
    123
    124static 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
    134static 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
    145struct telem_pss_ltr_info {
    146	const char *name;
    147	u32 bit_pos;
    148};
    149
    150static 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
    160struct telem_pss_wakeup_info {
    161	const char *name;
    162	u32 bit_pos;
    163};
    164
    165static 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
    175struct telem_ioss_d0ix_stateinfo {
    176	const char *name;
    177	u32 bit_pos;
    178};
    179
    180static 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
    202struct telem_ioss_pg_info {
    203	const char *name;
    204	u32 bit_pos;
    205};
    206
    207static 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
    236struct 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
    274static struct telemetry_debugfs_conf *debugfs_conf;
    275
    276static 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
    310static const struct x86_cpu_id telemetry_debugfs_cpu_ids[] = {
    311	X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT,	&telem_apl_debugfs_conf),
    312	X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_PLUS,	&telem_apl_debugfs_conf),
    313	{}
    314};
    315MODULE_DEVICE_TABLE(x86cpu, telemetry_debugfs_cpu_ids);
    316
    317static int telemetry_debugfs_check_evts(void)
    318{
    319	if ((debugfs_conf->pss_idle_evts > TELEM_PSS_IDLE_EVTS) ||
    320	    (debugfs_conf->pcs_idle_blkd_evts > TELEM_PSS_IDLE_BLOCKED_EVTS) ||
    321	    (debugfs_conf->pcs_s0ix_blkd_evts > TELEM_PSS_S0IX_BLOCKED_EVTS) ||
    322	    (debugfs_conf->pss_ltr_evts > TELEM_PSS_LTR_BLOCKING_EVTS) ||
    323	    (debugfs_conf->pss_wakeup_evts > TELEM_PSS_S0IX_WAKEUP_EVTS) ||
    324	    (debugfs_conf->ioss_d0ix_evts > TELEM_IOSS_DX_D0IX_EVTS) ||
    325	    (debugfs_conf->ioss_pg_evts > TELEM_IOSS_PG_EVTS))
    326		return -EINVAL;
    327
    328	return 0;
    329}
    330
    331static int telem_pss_states_show(struct seq_file *s, void *unused)
    332{
    333	struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
    334	struct telemetry_debugfs_conf *conf = debugfs_conf;
    335	const char *name[TELEM_MAX_OS_ALLOCATED_EVENTS];
    336	u32 pcs_idle_blkd[TELEM_PSS_IDLE_BLOCKED_EVTS],
    337	    pcs_s0ix_blkd[TELEM_PSS_S0IX_BLOCKED_EVTS],
    338	    pss_s0ix_wakeup[TELEM_PSS_S0IX_WAKEUP_EVTS],
    339	    pss_ltr_blkd[TELEM_PSS_LTR_BLOCKING_EVTS],
    340	    pss_idle[TELEM_PSS_IDLE_EVTS];
    341	int index, idx, ret, err = 0;
    342	u64 pstates = 0;
    343
    344	ret = telemetry_read_eventlog(TELEM_PSS, evtlog,
    345				      TELEM_MAX_OS_ALLOCATED_EVENTS);
    346	if (ret < 0)
    347		return ret;
    348
    349	err = telemetry_get_evtname(TELEM_PSS, name,
    350				    TELEM_MAX_OS_ALLOCATED_EVENTS);
    351	if (err < 0)
    352		return err;
    353
    354	seq_puts(s, "\n----------------------------------------------------\n");
    355	seq_puts(s, "\tPSS TELEM EVENTLOG (Residency = field/19.2 us\n");
    356	seq_puts(s, "----------------------------------------------------\n");
    357	for (index = 0; index < ret; index++) {
    358		seq_printf(s, "%-32s %llu\n",
    359			   name[index], evtlog[index].telem_evtlog);
    360
    361		/* Fetch PSS IDLE State */
    362		if (evtlog[index].telem_evtid == conf->pss_idle_id) {
    363			pss_idle[conf->pss_idle_evts - 1] =
    364			(evtlog[index].telem_evtlog >>
    365			conf->pss_idle_data[conf->pss_idle_evts - 1].bit_pos) &
    366			TELEM_APL_MASK_PCS_STATE;
    367		}
    368
    369		TELEM_CHECK_AND_PARSE_EVTS(conf->pss_idle_id,
    370					   conf->pss_idle_evts - 1,
    371					   pss_idle, evtlog[index].telem_evtlog,
    372					   conf->pss_idle_data, TELEM_MASK_BIT);
    373
    374		TELEM_CHECK_AND_PARSE_EVTS(conf->pcs_idle_blkd_id,
    375					   conf->pcs_idle_blkd_evts,
    376					   pcs_idle_blkd,
    377					   evtlog[index].telem_evtlog,
    378					   conf->pcs_idle_blkd_data,
    379					   TELEM_MASK_BYTE);
    380
    381		TELEM_CHECK_AND_PARSE_EVTS(conf->pcs_s0ix_blkd_id,
    382					   conf->pcs_s0ix_blkd_evts,
    383					   pcs_s0ix_blkd,
    384					   evtlog[index].telem_evtlog,
    385					   conf->pcs_s0ix_blkd_data,
    386					   TELEM_MASK_BYTE);
    387
    388		TELEM_CHECK_AND_PARSE_EVTS(conf->pss_wakeup_id,
    389					   conf->pss_wakeup_evts,
    390					   pss_s0ix_wakeup,
    391					   evtlog[index].telem_evtlog,
    392					   conf->pss_wakeup, TELEM_MASK_BYTE);
    393
    394		TELEM_CHECK_AND_PARSE_EVTS(conf->pss_ltr_blocking_id,
    395					   conf->pss_ltr_evts, pss_ltr_blkd,
    396					   evtlog[index].telem_evtlog,
    397					   conf->pss_ltr_data, TELEM_MASK_BYTE);
    398
    399		if (evtlog[index].telem_evtid == debugfs_conf->pstates_id)
    400			pstates = evtlog[index].telem_evtlog;
    401	}
    402
    403	seq_puts(s, "\n--------------------------------------\n");
    404	seq_puts(s, "PStates\n");
    405	seq_puts(s, "--------------------------------------\n");
    406	seq_puts(s, "Domain\t\t\t\tFreq(Mhz)\n");
    407	seq_printf(s, " IA\t\t\t\t %llu\n GT\t\t\t\t %llu\n",
    408		   (pstates & TELEM_MASK_BYTE)*100,
    409		   ((pstates >> 8) & TELEM_MASK_BYTE)*50/3);
    410
    411	seq_printf(s, " IUNIT\t\t\t\t %llu\n SA\t\t\t\t %llu\n",
    412		   ((pstates >> 16) & TELEM_MASK_BYTE)*25,
    413		   ((pstates >> 24) & TELEM_MASK_BYTE)*50/3);
    414
    415	seq_puts(s, "\n--------------------------------------\n");
    416	seq_puts(s, "PSS IDLE Status\n");
    417	seq_puts(s, "--------------------------------------\n");
    418	seq_puts(s, "Device\t\t\t\t\tIDLE\n");
    419	for (index = 0; index < debugfs_conf->pss_idle_evts; index++) {
    420		seq_printf(s, "%-32s\t%u\n",
    421			   debugfs_conf->pss_idle_data[index].name,
    422			   pss_idle[index]);
    423	}
    424
    425	seq_puts(s, "\n--------------------------------------\n");
    426	seq_puts(s, "PSS Idle blkd Status (~1ms saturating bucket)\n");
    427	seq_puts(s, "--------------------------------------\n");
    428	seq_puts(s, "Blocker\t\t\t\t\tCount\n");
    429	for (index = 0; index < debugfs_conf->pcs_idle_blkd_evts; index++) {
    430		seq_printf(s, "%-32s\t%u\n",
    431			   debugfs_conf->pcs_idle_blkd_data[index].name,
    432			   pcs_idle_blkd[index]);
    433	}
    434
    435	seq_puts(s, "\n--------------------------------------\n");
    436	seq_puts(s, "PSS S0ix blkd Status (~1ms saturating bucket)\n");
    437	seq_puts(s, "--------------------------------------\n");
    438	seq_puts(s, "Blocker\t\t\t\t\tCount\n");
    439	for (index = 0; index < debugfs_conf->pcs_s0ix_blkd_evts; index++) {
    440		seq_printf(s, "%-32s\t%u\n",
    441			   debugfs_conf->pcs_s0ix_blkd_data[index].name,
    442			   pcs_s0ix_blkd[index]);
    443	}
    444
    445	seq_puts(s, "\n--------------------------------------\n");
    446	seq_puts(s, "LTR Blocking Status (~1ms saturating bucket)\n");
    447	seq_puts(s, "--------------------------------------\n");
    448	seq_puts(s, "Blocker\t\t\t\t\tCount\n");
    449	for (index = 0; index < debugfs_conf->pss_ltr_evts; index++) {
    450		seq_printf(s, "%-32s\t%u\n",
    451			   debugfs_conf->pss_ltr_data[index].name,
    452			   pss_s0ix_wakeup[index]);
    453	}
    454
    455	seq_puts(s, "\n--------------------------------------\n");
    456	seq_puts(s, "Wakes Status (~1ms saturating bucket)\n");
    457	seq_puts(s, "--------------------------------------\n");
    458	seq_puts(s, "Wakes\t\t\t\t\tCount\n");
    459	for (index = 0; index < debugfs_conf->pss_wakeup_evts; index++) {
    460		seq_printf(s, "%-32s\t%u\n",
    461			   debugfs_conf->pss_wakeup[index].name,
    462			   pss_ltr_blkd[index]);
    463	}
    464
    465	return 0;
    466}
    467
    468DEFINE_SHOW_ATTRIBUTE(telem_pss_states);
    469
    470static int telem_ioss_states_show(struct seq_file *s, void *unused)
    471{
    472	struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
    473	const char *name[TELEM_MAX_OS_ALLOCATED_EVENTS];
    474	int index, ret, err;
    475
    476	ret = telemetry_read_eventlog(TELEM_IOSS, evtlog,
    477				      TELEM_MAX_OS_ALLOCATED_EVENTS);
    478	if (ret < 0)
    479		return ret;
    480
    481	err = telemetry_get_evtname(TELEM_IOSS, name,
    482				    TELEM_MAX_OS_ALLOCATED_EVENTS);
    483	if (err < 0)
    484		return err;
    485
    486	seq_puts(s, "--------------------------------------\n");
    487	seq_puts(s, "\tI0SS TELEMETRY EVENTLOG\n");
    488	seq_puts(s, "--------------------------------------\n");
    489	for (index = 0; index < ret; index++) {
    490		seq_printf(s, "%-32s 0x%llx\n",
    491			   name[index], evtlog[index].telem_evtlog);
    492	}
    493
    494	return 0;
    495}
    496
    497DEFINE_SHOW_ATTRIBUTE(telem_ioss_states);
    498
    499static int telem_soc_states_show(struct seq_file *s, void *unused)
    500{
    501	u32 d3_sts[TELEM_IOSS_DX_D0IX_EVTS], d0ix_sts[TELEM_IOSS_DX_D0IX_EVTS];
    502	u32 pg_sts[TELEM_IOSS_PG_EVTS], pss_idle[TELEM_PSS_IDLE_EVTS];
    503	struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
    504	u32 s0ix_total_ctr = 0, s0ix_shlw_ctr = 0, s0ix_deep_ctr = 0;
    505	u64 s0ix_total_res = 0, s0ix_shlw_res = 0, s0ix_deep_res = 0;
    506	struct telemetry_debugfs_conf *conf = debugfs_conf;
    507	struct pci_dev *dev = NULL;
    508	int index, idx, ret;
    509	u32 d3_state;
    510	u16 pmcsr;
    511
    512	ret = telemetry_read_eventlog(TELEM_IOSS, evtlog,
    513				      TELEM_MAX_OS_ALLOCATED_EVENTS);
    514	if (ret < 0)
    515		return ret;
    516
    517	for (index = 0; index < ret; index++) {
    518		TELEM_CHECK_AND_PARSE_EVTS(conf->ioss_d3_id,
    519					   conf->ioss_d0ix_evts,
    520					   d3_sts, evtlog[index].telem_evtlog,
    521					   conf->ioss_d0ix_data,
    522					   TELEM_MASK_BIT);
    523
    524		TELEM_CHECK_AND_PARSE_EVTS(conf->ioss_pg_id, conf->ioss_pg_evts,
    525					   pg_sts, evtlog[index].telem_evtlog,
    526					   conf->ioss_pg_data, TELEM_MASK_BIT);
    527
    528		TELEM_CHECK_AND_PARSE_EVTS(conf->ioss_d0ix_id,
    529					   conf->ioss_d0ix_evts,
    530					   d0ix_sts, evtlog[index].telem_evtlog,
    531					   conf->ioss_d0ix_data,
    532					   TELEM_MASK_BIT);
    533
    534		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_total_occ_id,
    535					   s0ix_total_ctr);
    536
    537		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_occ_id,
    538					   s0ix_shlw_ctr);
    539
    540		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_occ_id,
    541					   s0ix_deep_ctr);
    542
    543		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_total_res_id,
    544					   s0ix_total_res);
    545
    546		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_res_id,
    547					   s0ix_shlw_res);
    548
    549		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_res_id,
    550					   s0ix_deep_res);
    551	}
    552
    553	seq_puts(s, "\n---------------------------------------------------\n");
    554	seq_puts(s, "S0IX Type\t\t\t Occurrence\t\t Residency(us)\n");
    555	seq_puts(s, "---------------------------------------------------\n");
    556
    557	seq_printf(s, "S0IX Shallow\t\t\t %10u\t %10llu\n",
    558		   s0ix_shlw_ctr -
    559		   conf->suspend_stats.shlw_ctr,
    560		   (u64)((s0ix_shlw_res -
    561		   conf->suspend_stats.shlw_res)*10/192));
    562
    563	seq_printf(s, "S0IX Deep\t\t\t %10u\t %10llu\n",
    564		   s0ix_deep_ctr -
    565		   conf->suspend_stats.deep_ctr,
    566		   (u64)((s0ix_deep_res -
    567		   conf->suspend_stats.deep_res)*10/192));
    568
    569	seq_printf(s, "Suspend(With S0ixShallow)\t %10u\t %10llu\n",
    570		   conf->suspend_stats.shlw_ctr,
    571		   (u64)(conf->suspend_stats.shlw_res*10)/192);
    572
    573	seq_printf(s, "Suspend(With S0ixDeep)\t\t %10u\t %10llu\n",
    574		   conf->suspend_stats.deep_ctr,
    575		   (u64)(conf->suspend_stats.deep_res*10)/192);
    576
    577	seq_printf(s, "TOTAL S0IX\t\t\t %10u\t %10llu\n", s0ix_total_ctr,
    578		   (u64)(s0ix_total_res*10/192));
    579	seq_puts(s, "\n-------------------------------------------------\n");
    580	seq_puts(s, "\t\tDEVICE STATES\n");
    581	seq_puts(s, "-------------------------------------------------\n");
    582
    583	for_each_pci_dev(dev) {
    584		pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
    585		d3_state = ((pmcsr & PCI_PM_CTRL_STATE_MASK) ==
    586			    (__force int)PCI_D3hot) ? 1 : 0;
    587
    588		seq_printf(s, "pci %04x %04X %s %20.20s: ",
    589			   dev->vendor, dev->device, dev_name(&dev->dev),
    590			   dev_driver_string(&dev->dev));
    591		seq_printf(s, " d3:%x\n", d3_state);
    592	}
    593
    594	seq_puts(s, "\n--------------------------------------\n");
    595	seq_puts(s, "D3/D0i3 Status\n");
    596	seq_puts(s, "--------------------------------------\n");
    597	seq_puts(s, "Block\t\t D3\t D0i3\n");
    598	for (index = 0; index < conf->ioss_d0ix_evts; index++) {
    599		seq_printf(s, "%-10s\t %u\t %u\n",
    600			   conf->ioss_d0ix_data[index].name,
    601			   d3_sts[index], d0ix_sts[index]);
    602	}
    603
    604	seq_puts(s, "\n--------------------------------------\n");
    605	seq_puts(s, "South Complex PowerGate Status\n");
    606	seq_puts(s, "--------------------------------------\n");
    607	seq_puts(s, "Device\t\t PG\n");
    608	for (index = 0; index < conf->ioss_pg_evts; index++) {
    609		seq_printf(s, "%-10s\t %u\n",
    610			   conf->ioss_pg_data[index].name,
    611			   pg_sts[index]);
    612	}
    613
    614	evtlog->telem_evtid = conf->pss_idle_id;
    615	ret = telemetry_read_events(TELEM_PSS, evtlog, 1);
    616	if (ret < 0)
    617		return ret;
    618
    619	seq_puts(s, "\n-----------------------------------------\n");
    620	seq_puts(s, "North Idle Status\n");
    621	seq_puts(s, "-----------------------------------------\n");
    622	for (idx = 0; idx < conf->pss_idle_evts - 1; idx++) {
    623		pss_idle[idx] =	(evtlog->telem_evtlog >>
    624				conf->pss_idle_data[idx].bit_pos) &
    625				TELEM_MASK_BIT;
    626	}
    627
    628	pss_idle[idx] = (evtlog->telem_evtlog >>
    629			conf->pss_idle_data[idx].bit_pos) &
    630			TELEM_APL_MASK_PCS_STATE;
    631
    632	for (index = 0; index < conf->pss_idle_evts; index++) {
    633		seq_printf(s, "%-30s %u\n",
    634			   conf->pss_idle_data[index].name,
    635			   pss_idle[index]);
    636	}
    637
    638	seq_puts(s, "\nPCS_STATUS Code\n");
    639	seq_puts(s, "0:C0 1:C1 2:C1_DN_WT_DEV 3:C2 4:C2_WT_DE_MEM_UP\n");
    640	seq_puts(s, "5:C2_WT_DE_MEM_DOWN 6:C2_UP_WT_DEV 7:C2_DN 8:C2_VOA\n");
    641	seq_puts(s, "9:C2_VOA_UP 10:S0IX_PRE 11:S0IX\n");
    642
    643	return 0;
    644}
    645
    646DEFINE_SHOW_ATTRIBUTE(telem_soc_states);
    647
    648static int telem_s0ix_res_get(void *data, u64 *val)
    649{
    650	struct telemetry_plt_config *plt_config = telemetry_get_pltdata();
    651	u64 s0ix_total_res;
    652	int ret;
    653
    654	ret = intel_pmc_s0ix_counter_read(plt_config->pmc, &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
    665DEFINE_DEBUGFS_ATTRIBUTE(telem_s0ix_fops, telem_s0ix_res_get, NULL, "%llu\n");
    666
    667static 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
    682static 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	err = kstrtou32_from_user(userbuf, count, 0, &verbosity);
    690	if (err)
    691		return err;
    692
    693	err = telemetry_set_trace_verbosity(TELEM_PSS, verbosity);
    694	if (err) {
    695		pr_err("Changing PSS Trace Verbosity Failed. Error %d\n", err);
    696		return err;
    697	}
    698
    699	return count;
    700}
    701
    702static int telem_pss_trc_verb_open(struct inode *inode, struct file *file)
    703{
    704	return single_open(file, telem_pss_trc_verb_show, inode->i_private);
    705}
    706
    707static const struct file_operations telem_pss_trc_verb_ops = {
    708	.open		= telem_pss_trc_verb_open,
    709	.read		= seq_read,
    710	.write		= telem_pss_trc_verb_write,
    711	.llseek		= seq_lseek,
    712	.release	= single_release,
    713};
    714
    715static int telem_ioss_trc_verb_show(struct seq_file *s, void *unused)
    716{
    717	u32 verbosity;
    718	int err;
    719
    720	err = telemetry_get_trace_verbosity(TELEM_IOSS, &verbosity);
    721	if (err) {
    722		pr_err("Get IOSS Trace Verbosity Failed with Error %d\n", err);
    723		return -EFAULT;
    724	}
    725
    726	seq_printf(s, "IOSS Trace Verbosity %u\n", verbosity);
    727	return 0;
    728}
    729
    730static ssize_t telem_ioss_trc_verb_write(struct file *file,
    731					 const char __user *userbuf,
    732					 size_t count, loff_t *ppos)
    733{
    734	u32 verbosity;
    735	int err;
    736
    737	err = kstrtou32_from_user(userbuf, count, 0, &verbosity);
    738	if (err)
    739		return err;
    740
    741	err = telemetry_set_trace_verbosity(TELEM_IOSS, verbosity);
    742	if (err) {
    743		pr_err("Changing IOSS Trace Verbosity Failed. Error %d\n", err);
    744		return err;
    745	}
    746
    747	return count;
    748}
    749
    750static int telem_ioss_trc_verb_open(struct inode *inode, struct file *file)
    751{
    752	return single_open(file, telem_ioss_trc_verb_show, inode->i_private);
    753}
    754
    755static const struct file_operations telem_ioss_trc_verb_ops = {
    756	.open		= telem_ioss_trc_verb_open,
    757	.read		= seq_read,
    758	.write		= telem_ioss_trc_verb_write,
    759	.llseek		= seq_lseek,
    760	.release	= single_release,
    761};
    762
    763static int pm_suspend_prep_cb(void)
    764{
    765	struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
    766	struct telemetry_debugfs_conf *conf = debugfs_conf;
    767	int ret, index;
    768
    769	ret = telemetry_raw_read_eventlog(TELEM_IOSS, evtlog,
    770			TELEM_MAX_OS_ALLOCATED_EVENTS);
    771	if (ret < 0) {
    772		suspend_prep_ok = 0;
    773		goto out;
    774	}
    775
    776	for (index = 0; index < ret; index++) {
    777
    778		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_occ_id,
    779					   suspend_shlw_ctr_temp);
    780
    781		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_occ_id,
    782					   suspend_deep_ctr_temp);
    783
    784		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_res_id,
    785					   suspend_shlw_res_temp);
    786
    787		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_res_id,
    788					   suspend_deep_res_temp);
    789	}
    790	suspend_prep_ok = 1;
    791out:
    792	return NOTIFY_OK;
    793}
    794
    795static int pm_suspend_exit_cb(void)
    796{
    797	struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
    798	static u32 suspend_shlw_ctr_exit, suspend_deep_ctr_exit;
    799	static u64 suspend_shlw_res_exit, suspend_deep_res_exit;
    800	struct telemetry_debugfs_conf *conf = debugfs_conf;
    801	int ret, index;
    802
    803	if (!suspend_prep_ok)
    804		goto out;
    805
    806	ret = telemetry_raw_read_eventlog(TELEM_IOSS, evtlog,
    807					  TELEM_MAX_OS_ALLOCATED_EVENTS);
    808	if (ret < 0)
    809		goto out;
    810
    811	for (index = 0; index < ret; index++) {
    812		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_occ_id,
    813					   suspend_shlw_ctr_exit);
    814
    815		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_occ_id,
    816					   suspend_deep_ctr_exit);
    817
    818		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_shlw_res_id,
    819					   suspend_shlw_res_exit);
    820
    821		TELEM_CHECK_AND_PARSE_CTRS(conf->s0ix_deep_res_id,
    822					   suspend_deep_res_exit);
    823	}
    824
    825	if ((suspend_shlw_ctr_exit < suspend_shlw_ctr_temp) ||
    826	    (suspend_deep_ctr_exit < suspend_deep_ctr_temp) ||
    827	    (suspend_shlw_res_exit < suspend_shlw_res_temp) ||
    828	    (suspend_deep_res_exit < suspend_deep_res_temp)) {
    829		pr_err("Wrong s0ix counters detected\n");
    830		goto out;
    831	}
    832
    833	/*
    834	 * Due to some design limitations in the firmware, sometimes the
    835	 * counters do not get updated by the time we reach here. As a
    836	 * workaround, we try to see if this was a genuine case of sleep
    837	 * failure or not by cross-checking from PMC GCR registers directly.
    838	 */
    839	if (suspend_shlw_ctr_exit == suspend_shlw_ctr_temp &&
    840	    suspend_deep_ctr_exit == suspend_deep_ctr_temp) {
    841		struct telemetry_plt_config *plt_config = telemetry_get_pltdata();
    842		struct intel_pmc_dev *pmc = plt_config->pmc;
    843
    844		ret = intel_pmc_gcr_read64(pmc, PMC_GCR_TELEM_SHLW_S0IX_REG,
    845					  &suspend_shlw_res_exit);
    846		if (ret < 0)
    847			goto out;
    848
    849		ret = intel_pmc_gcr_read64(pmc, PMC_GCR_TELEM_DEEP_S0IX_REG,
    850					  &suspend_deep_res_exit);
    851		if (ret < 0)
    852			goto out;
    853
    854		if (suspend_shlw_res_exit > suspend_shlw_res_temp)
    855			suspend_shlw_ctr_exit++;
    856
    857		if (suspend_deep_res_exit > suspend_deep_res_temp)
    858			suspend_deep_ctr_exit++;
    859	}
    860
    861	suspend_shlw_ctr_exit -= suspend_shlw_ctr_temp;
    862	suspend_deep_ctr_exit -= suspend_deep_ctr_temp;
    863	suspend_shlw_res_exit -= suspend_shlw_res_temp;
    864	suspend_deep_res_exit -= suspend_deep_res_temp;
    865
    866	if (suspend_shlw_ctr_exit != 0) {
    867		conf->suspend_stats.shlw_ctr +=
    868		suspend_shlw_ctr_exit;
    869
    870		conf->suspend_stats.shlw_res +=
    871		suspend_shlw_res_exit;
    872	}
    873
    874	if (suspend_deep_ctr_exit != 0) {
    875		conf->suspend_stats.deep_ctr +=
    876		suspend_deep_ctr_exit;
    877
    878		conf->suspend_stats.deep_res +=
    879		suspend_deep_res_exit;
    880	}
    881
    882out:
    883	suspend_prep_ok = 0;
    884	return NOTIFY_OK;
    885}
    886
    887static int pm_notification(struct notifier_block *this,
    888			   unsigned long event, void *ptr)
    889{
    890	switch (event) {
    891	case PM_SUSPEND_PREPARE:
    892		return pm_suspend_prep_cb();
    893	case PM_POST_SUSPEND:
    894		return pm_suspend_exit_cb();
    895	}
    896
    897	return NOTIFY_DONE;
    898}
    899
    900static struct notifier_block pm_notifier = {
    901	.notifier_call = pm_notification,
    902};
    903
    904static int __init telemetry_debugfs_init(void)
    905{
    906	const struct x86_cpu_id *id;
    907	int err;
    908	struct dentry *dir;
    909
    910	/* Only APL supported for now */
    911	id = x86_match_cpu(telemetry_debugfs_cpu_ids);
    912	if (!id)
    913		return -ENODEV;
    914
    915	debugfs_conf = (struct telemetry_debugfs_conf *)id->driver_data;
    916
    917	if (!telemetry_get_pltdata()) {
    918		pr_info("Invalid pltconfig, ensure IPC1 device is enabled in BIOS\n");
    919		return -ENODEV;
    920	}
    921
    922	err = telemetry_debugfs_check_evts();
    923	if (err < 0) {
    924		pr_info("telemetry_debugfs_check_evts failed\n");
    925		return -EINVAL;
    926	}
    927
    928	register_pm_notifier(&pm_notifier);
    929
    930	dir = debugfs_create_dir("telemetry", NULL);
    931	debugfs_conf->telemetry_dbg_dir = dir;
    932
    933	debugfs_create_file("pss_info", S_IFREG | S_IRUGO, dir, NULL,
    934			    &telem_pss_states_fops);
    935	debugfs_create_file("ioss_info", S_IFREG | S_IRUGO, dir, NULL,
    936			    &telem_ioss_states_fops);
    937	debugfs_create_file("soc_states", S_IFREG | S_IRUGO, dir, NULL,
    938			    &telem_soc_states_fops);
    939	debugfs_create_file("s0ix_residency_usec", S_IFREG | S_IRUGO, dir, NULL,
    940			    &telem_s0ix_fops);
    941	debugfs_create_file("pss_trace_verbosity", S_IFREG | S_IRUGO, dir, NULL,
    942			    &telem_pss_trc_verb_ops);
    943	debugfs_create_file("ioss_trace_verbosity", S_IFREG | S_IRUGO, dir,
    944			    NULL, &telem_ioss_trc_verb_ops);
    945	return 0;
    946}
    947
    948static void __exit telemetry_debugfs_exit(void)
    949{
    950	debugfs_remove_recursive(debugfs_conf->telemetry_dbg_dir);
    951	debugfs_conf->telemetry_dbg_dir = NULL;
    952	unregister_pm_notifier(&pm_notifier);
    953}
    954
    955late_initcall(telemetry_debugfs_init);
    956module_exit(telemetry_debugfs_exit);
    957
    958MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
    959MODULE_DESCRIPTION("Intel SoC Telemetry debugfs Interface");
    960MODULE_VERSION(DRIVER_VERSION);
    961MODULE_LICENSE("GPL v2");