2020-01-24 21:00:05

by Kammela, Gayatri

[permalink] [raw]
Subject: [PATCH v1 0/7] platform/x86: intel_pmc_core: Add debugfs entries

Hi,

Tiger Lake platform supports 8 sub-states/low power modes of S0ix. Add
debugfs entries to pmc_core driver to access low power mode registers
and residencies.

Patch 1: Add debugfs entry to access sub-state residencies
Patch 2: Add debugfs entry for low power mode status registers
Patch 3: Refactor the driver by removing redundant code
Patch 4: Remove slp_s0 attributes from tgl_reg_map
Patch 5: Add an additional parameter to pmc_core_lpm_display_map()
Patch 6: Dump low power status registers on an S0ix.y failure
Patch 7: Add debugfs support to access live status registers

Gayatri Kammela (7):
platform/x86: intel_pmc_core: Add debugfs entry to access sub-state
residencies
platform/x86: intel_pmc_core: Add debugfs entry for low power mode
status registers
platform/x86: intel_pmc_core: Refactor the driver by removing
redundant code
platform/x86: intel_pmc_core: Remove slp_s0 attributes from
tgl_reg_map
platform/x86: intel_pmc_core: Add an additional parameter to
pmc_core_lpm_display()
platform/x86: intel_pmc_core: Dump low power status registers on an
S0ix.y failure
platform/x86: intel_pmc_core: Add debugfs support to access live
status registers

drivers/platform/x86/intel_pmc_core.c | 301 +++++++++++++++++++++++---
drivers/platform/x86/intel_pmc_core.h | 28 +++
2 files changed, 302 insertions(+), 27 deletions(-)

Cc: Srinivas Pandruvada <[email protected]>
Cc: Andy Shevchenko <[email protected]>
Cc: David Box <[email protected]>
--
2.17.1


2020-01-24 21:00:09

by Kammela, Gayatri

[permalink] [raw]
Subject: [PATCH v1 1/7] platform/x86: intel_pmc_core: Add debugfs entry to access sub-state residencies

Prior to Tiger Lake, the platforms that support pmc_core have no
sub-states of S0ix. Tiger Lake has 8 sub-states/low power modes of S0ix
ranging from S0i2.0-S0i2.2 and S0i3.0-S0i3.4, simply represented as
S0ix.y.

Create a debugfs entry to access residency of each sub-state.

Cc: Srinivas Pandruvada <[email protected]>
Cc: Andy Shevchenko <[email protected]>
Cc: David Box <[email protected]>
Signed-off-by: David Box <[email protected]>
Signed-off-by: Gayatri Kammela <[email protected]>
---
drivers/platform/x86/intel_pmc_core.c | 28 +++++++++++++++++++++++++++
drivers/platform/x86/intel_pmc_core.h | 21 ++++++++++++++++++++
2 files changed, 49 insertions(+)

diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c
index 017776551cc5..6e7cf620bea6 100644
--- a/drivers/platform/x86/intel_pmc_core.c
+++ b/drivers/platform/x86/intel_pmc_core.c
@@ -422,6 +422,8 @@ static const struct pmc_reg_map tgl_reg_map = {
.pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET,
.pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT,
.ltr_ignore_max = TGL_NUM_IP_IGN_ALLOWED,
+ .lpm_en_offset = TGL_LPM_EN_OFFSET,
+ .lpm_residency_offset = TGL_LPM_RESIDENCY_OFFSET,
};

static inline u8 pmc_core_reg_read_byte(struct pmc_dev *pmcdev, int offset)
@@ -793,6 +795,26 @@ static int pmc_core_ltr_show(struct seq_file *s, void *unused)
}
DEFINE_SHOW_ATTRIBUTE(pmc_core_ltr);

+static int pmc_core_substate_res_show(struct seq_file *s, void *unused)
+{
+ struct pmc_dev *pmcdev = s->private;
+ u32 offset = pmcdev->map->lpm_residency_offset;
+ u32 lpm_en;
+ int index;
+
+ lpm_en = pmc_core_reg_read(pmcdev, pmcdev->map->lpm_en_offset);
+ seq_printf(s, "status substate residency\n");
+ for (index = 0; lpm_modes[index]; index++) {
+ seq_printf(s, "%7s %7s %-15u\n",
+ BIT(index) & lpm_en ? "Enabled" : " ",
+ lpm_modes[index], pmc_core_reg_read(pmcdev, offset));
+ offset += 4;
+ }
+
+ return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(pmc_core_substate_res);
+
static int pmc_core_pkgc_show(struct seq_file *s, void *unused)
{
struct pmc_dev *pmcdev = s->private;
@@ -858,6 +880,12 @@ static void pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
debugfs_create_bool("slp_s0_dbg_latch", 0644,
dir, &slps0_dbg_latch);
}
+
+ if (pmcdev->map->lpm_en_offset) {
+ debugfs_create_file("substate_residencies", 0444,
+ pmcdev->dbgfs_dir, pmcdev,
+ &pmc_core_substate_res_fops);
+ }
}
#else
static inline void pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
diff --git a/drivers/platform/x86/intel_pmc_core.h b/drivers/platform/x86/intel_pmc_core.h
index f1a0792b3f91..ff1b2645d9b4 100644
--- a/drivers/platform/x86/intel_pmc_core.h
+++ b/drivers/platform/x86/intel_pmc_core.h
@@ -188,6 +188,24 @@ enum ppfear_regs {

#define TGL_NUM_IP_IGN_ALLOWED 22

+/*
+ * Tigerlake Power Management Controller register offsets
+ */
+#define TGL_LPM_EN_OFFSET 0x1C78
+#define TGL_LPM_RESIDENCY_OFFSET 0x1C80
+
+const char *lpm_modes[] = {
+ "S0i2.0",
+ "S0i2.1",
+ "S0i2.2",
+ "S0i3.0",
+ "S0i3.1",
+ "S0i3.2",
+ "S0i3.3",
+ "S0i3.4",
+ NULL
+};
+
struct pmc_bit_map {
const char *name;
u32 bit_mask;
@@ -231,6 +249,9 @@ struct pmc_reg_map {
const u32 slps0_dbg_offset;
const u32 ltr_ignore_max;
const u32 pm_vric1_offset;
+ /* Low Power Mode registers */
+ const u32 lpm_en_offset;
+ const u32 lpm_residency_offset;
};

/**
--
2.17.1

2020-01-24 21:00:11

by Kammela, Gayatri

[permalink] [raw]
Subject: [PATCH v1 2/7] platform/x86: intel_pmc_core: Add debugfs entry for low power mode status registers

Tiger Lake has 6 status registers that are memory mapped. These
registers show the status of the low power mode requirements. The
registers are latched on every C10 entry or exit and on every s0ix.y
entry/exit. Accessing these registers is useful for debugging any low
power related activities.

Thus, add debugfs entry to access low power mode status registers.

Cc: Srinivas Pandruvada <[email protected]>
Cc: Andy Shevchenko <[email protected]>
Cc: David Box <[email protected]>
Signed-off-by: David Box <[email protected]>
Signed-off-by: Gayatri Kammela <[email protected]>
---
drivers/platform/x86/intel_pmc_core.c | 188 ++++++++++++++++++++++++++
drivers/platform/x86/intel_pmc_core.h | 5 +
2 files changed, 193 insertions(+)

diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c
index 6e7cf620bea6..4019f517167b 100644
--- a/drivers/platform/x86/intel_pmc_core.c
+++ b/drivers/platform/x86/intel_pmc_core.c
@@ -408,6 +408,152 @@ static const struct pmc_reg_map icl_reg_map = {
.ltr_ignore_max = ICL_NUM_IP_IGN_ALLOWED,
};

+static const struct pmc_bit_map tgl_lpm0_map[] = {
+ {"USB2PLL_OFF_STS", BIT(18)},
+ {"PCIe/USB3.1_Gen2PLL_OFF_STS", BIT(19)},
+ {"PCIe_Gen3PLL_OFF_STS", BIT(20)},
+ {"OPIOPLL_OFF_STS", BIT(21)},
+ {"OCPLL_OFF_STS", BIT(22)},
+ {"AudioPLL_OFF_STS", BIT(23)},
+ {"MIPIPLL_OFF_STS", BIT(24)},
+ {"Fast_XTAL_Osc_OFF_STS", BIT(25)},
+ {"AC_Ring_Osc_OFF_STS", BIT(26)},
+ {"MC_Ring_Osc_OFF_STS", BIT(27)},
+ {"SATAPLL_OFF_STS", BIT(29)},
+ {"XTAL_USB2PLL_OFF_STS", BIT(31)},
+ {}
+};
+
+static const struct pmc_bit_map tgl_lpm1_map[] = {
+ {"SPI_PG_STS", BIT(2)},
+ {"xHCI_PG_STS", BIT(3)},
+ {"PCIe_Ctrller_A_PG_STS", BIT(4)},
+ {"PCIe_Ctrller_B_PG_STS", BIT(5)},
+ {"PCIe_Ctrller_C_PG_STS", BIT(6)},
+ {"GBE_PG_STS", BIT(7)},
+ {"SATA_PG_STS", BIT(8)},
+ {"HDA0_PG_STS", BIT(9)},
+ {"HDA1_PG_STS", BIT(10)},
+ {"HDA2_PG_STS", BIT(11)},
+ {"HDA3_PG_STS", BIT(12)},
+ {"PCIe_Ctrller_D_PG_STS", BIT(13)},
+ {"ISIO_PG_STS", BIT(14)},
+ {"SMB_PG_STS", BIT(16)},
+ {"ISH_PG_STS", BIT(17)},
+ {"ITH_PG_STS", BIT(19)},
+ {"SDX_PG_STS", BIT(20)},
+ {"xDCI_PG_STS", BIT(25)},
+ {"DCI_PG_STS", BIT(26)},
+ {"CSME0_PG_STS", BIT(27)},
+ {"CSME_KVM_PG_STS", BIT(28)},
+ {"CSME1_PG_STS", BIT(29)},
+ {"CSME_CLINK_PG_STS", BIT(30)},
+ {"CSME2_PG_STS", BIT(31)},
+ {}
+};
+
+static const struct pmc_bit_map tgl_lpm2_map[] = {
+ {"ADSP_D3_STS", BIT(0)},
+ {"SATA_D3_STS", BIT(1)},
+ {"xHCI0_D3_STS", BIT(2)},
+ {"xDCI1_D3_STS", BIT(5)},
+ {"SDX_D3_STS", BIT(6)},
+ {"EMMC_D3_STS", BIT(7)},
+ {"IS_D3_STS", BIT(8)},
+ {"THC0_D3_STS", BIT(9)},
+ {"THC1_D3_STS", BIT(10)},
+ {"GBE_D3_STS", BIT(11)},
+ {"GBE_TSN_D3_STS", BIT(12)},
+ {}
+};
+
+static const struct pmc_bit_map tgl_lpm3_map[] = {
+ {"GPIO_COM0_VNN_REQ_STS", BIT(1)},
+ {"GPIO_COM1_VNN_REQ_STS", BIT(2)},
+ {"GPIO_COM2_VNN_REQ_STS", BIT(3)},
+ {"GPIO_COM3_VNN_REQ_STS", BIT(4)},
+ {"GPIO_COM4_VNN_REQ_STS", BIT(5)},
+ {"GPIO_COM5_VNN_REQ_STS", BIT(6)},
+ {"Audio_VNN_REQ_STS", BIT(7)},
+ {"ISH_VNN_REQ_STS", BIT(8)},
+ {"CNVI_VNN_REQ_STS", BIT(9)},
+ {"eSPI_VNN_REQ_STS", BIT(10)},
+ {"Display_VNN_REQ_STS", BIT(11)},
+ {"DTS_VNN_REQ_STS", BIT(12)},
+ {"SMBUS_VNN_REQ_STS", BIT(14)},
+ {"CSME_VNN_REQ_STS", BIT(15)},
+ {"SMLINK0_VNN_REQ_STS", BIT(16)},
+ {"SMLINK1_VNN_REQ_STS", BIT(17)},
+ {"CLINK_VNN_REQ_STS", BIT(20)},
+ {"DCI_VNN_REQ_STS", BIT(21)},
+ {"ITH_VNN_REQ_STS", BIT(22)},
+ {"CSME_VNN_REQ_STS", BIT(24)},
+ {"GBE_VNN_REQ_STS", BIT(25)},
+ {}
+};
+
+static const struct pmc_bit_map tgl_lpm4_map[] = {
+ {"CPU_C10_REQ_STS_0", BIT(0)},
+ {"PCIe_LPM_En_REQ_STS_3", BIT(3)},
+ {"ITH_REQ_STS_5", BIT(5)},
+ {"CNVI_REQ_STS_6", BIT(6)},
+ {"ISH_REQ_STS_7", BIT(7)},
+ {"USB2_SUS_PG_Sys_REQ_STS_10", BIT(10)},
+ {"PCIe_Clk_REQ_STS_12", BIT(12)},
+ {"MPHY_Core_DL_REQ_STS_16", BIT(16)},
+ {"Break-even_En_REQ_STS_17", BIT(17)},
+ {"Auto-demo_En_REQ_STS_18", BIT(18)},
+ {"MPHY_SUS_REQ_STS_22", BIT(22)},
+ {"xDCI_attached_REQ_STS_24", BIT(24)},
+ {}
+};
+
+static const struct pmc_bit_map tgl_lpm5_map[] = {
+ {"LSX_Wake0_En_STS", BIT(0)},
+ {"LSX_Wake0_Pol_STS", BIT(1)},
+ {"LSX_Wake1_En_STS", BIT(2)},
+ {"LSX_Wake1_Pol_STS", BIT(3)},
+ {"LSX_Wake2_En_STS", BIT(4)},
+ {"LSX_Wake2_Pol_STS", BIT(5)},
+ {"LSX_Wake3_En_STS", BIT(6)},
+ {"LSX_Wake3_Pol_STS", BIT(7)},
+ {"LSX_Wake4_En_STS", BIT(8)},
+ {"LSX_Wake4_Pol_STS", BIT(9)},
+ {"LSX_Wake5_En_STS", BIT(10)},
+ {"LSX_Wake5_Pol_STS", BIT(11)},
+ {"LSX_Wake6_En_STS", BIT(12)},
+ {"LSX_Wake6_Pol_STS", BIT(13)},
+ {"LSX_Wake7_En_STS", BIT(14)},
+ {"LSX_Wake7_Pol_STS", BIT(15)},
+ {"Intel_Se_IO_Wake0_En_STS", BIT(16)},
+ {"Intel_Se_IO_Wake0_Pol_STS", BIT(17)},
+ {"Intel_Se_IO_Wake1_En_STS", BIT(18)},
+ {"Intel_Se_IO_Wake1_Pol_STS", BIT(19)},
+ {"Int_Timer_SS_Wake0_En_STS", BIT(20)},
+ {"Int_Timer_SS_Wake0_Pol_STS", BIT(21)},
+ {"Int_Timer_SS_Wake1_En_STS", BIT(22)},
+ {"Int_Timer_SS_Wake1_Pol_STS", BIT(23)},
+ {"Int_Timer_SS_Wake2_En_STS", BIT(24)},
+ {"Int_Timer_SS_Wake2_Pol_STS", BIT(25)},
+ {"Int_Timer_SS_Wake3_En_STS", BIT(26)},
+ {"Int_Timer_SS_Wake3_Pol_STS", BIT(27)},
+ {"Int_Timer_SS_Wake4_En_STS", BIT(28)},
+ {"Int_Timer_SS_Wake4_Pol_STS", BIT(29)},
+ {"Int_Timer_SS_Wake5_En_STS", BIT(30)},
+ {"Int_Timer_SS_Wake5_Pol_STS", BIT(31)},
+ {}
+};
+
+static const struct pmc_bit_map *tgl_lpm_maps[] = {
+ tgl_lpm0_map,
+ tgl_lpm1_map,
+ tgl_lpm2_map,
+ tgl_lpm3_map,
+ tgl_lpm4_map,
+ tgl_lpm5_map,
+ NULL
+};
+
static const struct pmc_reg_map tgl_reg_map = {
.pfear_sts = ext_tgl_pfear_map,
.slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET,
@@ -424,6 +570,8 @@ static const struct pmc_reg_map tgl_reg_map = {
.ltr_ignore_max = TGL_NUM_IP_IGN_ALLOWED,
.lpm_en_offset = TGL_LPM_EN_OFFSET,
.lpm_residency_offset = TGL_LPM_RESIDENCY_OFFSET,
+ .lpm_sts = tgl_lpm_maps,
+ .lpm_status_offset = TGL_LPM_STATUS_OFFSET,
};

static inline u8 pmc_core_reg_read_byte(struct pmc_dev *pmcdev, int offset)
@@ -815,6 +963,40 @@ static int pmc_core_substate_res_show(struct seq_file *s, void *unused)
}
DEFINE_SHOW_ATTRIBUTE(pmc_core_substate_res);

+static void pmc_core_lpm_display(struct pmc_dev *pmcdev, struct seq_file *s,
+ u32 offset, const char *str,
+ const struct pmc_bit_map **maps)
+{
+ u32 lpm_regs[ARRAY_SIZE(tgl_lpm_maps)-1];
+ int index, idx, len = 32, bit_mask;
+
+ for (index = 0; tgl_lpm_maps[index]; index++) {
+ lpm_regs[index] = pmc_core_reg_read(pmcdev, offset);
+ offset += 4;
+ }
+
+ for (idx = 0; maps[idx]; idx++) {
+ seq_printf(s, "\nLPM_%s_%d:\t0x%x\n", str, idx, lpm_regs[idx]);
+ for (index = 0; maps[idx][index].name && index < len; index++) {
+ bit_mask = maps[idx][index].bit_mask;
+ seq_printf(s, "%-30s %-30d\n", maps[idx][index].name,
+ lpm_regs[idx] & bit_mask ? 1 : 0);
+ }
+ }
+}
+
+static int pmc_core_substate_sts_regs_show(struct seq_file *s, void *unused)
+{
+ struct pmc_dev *pmcdev = s->private;
+ const struct pmc_bit_map **maps = pmcdev->map->lpm_sts;
+ u32 offset = pmcdev->map->lpm_status_offset;
+
+ pmc_core_lpm_display(pmcdev, s, offset, "STATUS", maps);
+
+ return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(pmc_core_substate_sts_regs);
+
static int pmc_core_pkgc_show(struct seq_file *s, void *unused)
{
struct pmc_dev *pmcdev = s->private;
@@ -886,6 +1068,12 @@ static void pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
pmcdev->dbgfs_dir, pmcdev,
&pmc_core_substate_res_fops);
}
+
+ if (pmcdev->map->lpm_status_offset) {
+ debugfs_create_file("substate_status_registers", 0444,
+ pmcdev->dbgfs_dir, pmcdev,
+ &pmc_core_substate_sts_regs_fops);
+ }
}
#else
static inline void pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
diff --git a/drivers/platform/x86/intel_pmc_core.h b/drivers/platform/x86/intel_pmc_core.h
index ff1b2645d9b4..3fdf4735c56f 100644
--- a/drivers/platform/x86/intel_pmc_core.h
+++ b/drivers/platform/x86/intel_pmc_core.h
@@ -194,6 +194,9 @@ enum ppfear_regs {
#define TGL_LPM_EN_OFFSET 0x1C78
#define TGL_LPM_RESIDENCY_OFFSET 0x1C80

+/* Tigerlake Low Power Mode debug registers */
+#define TGL_LPM_STATUS_OFFSET 0x1C3C
+
const char *lpm_modes[] = {
"S0i2.0",
"S0i2.1",
@@ -239,6 +242,7 @@ struct pmc_reg_map {
const struct pmc_bit_map **slps0_dbg_maps;
const struct pmc_bit_map *ltr_show_sts;
const struct pmc_bit_map *msr_sts;
+ const struct pmc_bit_map **lpm_sts;
const u32 slp_s0_offset;
const u32 ltr_ignore_offset;
const int regmap_length;
@@ -252,6 +256,7 @@ struct pmc_reg_map {
/* Low Power Mode registers */
const u32 lpm_en_offset;
const u32 lpm_residency_offset;
+ const u32 lpm_status_offset;
};

/**
--
2.17.1

2020-01-24 21:00:13

by Kammela, Gayatri

[permalink] [raw]
Subject: [PATCH v1 3/7] platform/x86: intel_pmc_core: Refactor the driver by removing redundant code

pmc_core_slps0_dbg_show() is responsible for displaying debug registers
through slp_s0_debug_status entry. The driver uses the same but
redundant code to dump these debug registers for an S0ix failure.

Hence, refactor the driver by removing redundant code and reuse the
same function that both dumps registers through slp_s0_debug_status
entry and in resume for an S0ix failure.

The changes in this patch are preparatory, so platforms that support low
power sub-states can dump the debug registers when the attempt to enter
low power states are unsuccessful.

Cc: Srinivas Pandruvada <[email protected]>
Cc: Andy Shevchenko <[email protected]>
Cc: David Box <[email protected]>
Suggested-by: Andy Shevchenko <[email protected]>
Signed-off-by: Gayatri Kammela <[email protected]>
---
drivers/platform/x86/intel_pmc_core.c | 48 +++++++++++++--------------
1 file changed, 23 insertions(+), 25 deletions(-)

diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c
index 4019f517167b..f52348edab57 100644
--- a/drivers/platform/x86/intel_pmc_core.c
+++ b/drivers/platform/x86/intel_pmc_core.c
@@ -844,30 +844,41 @@ static void pmc_core_slps0_dbg_latch(struct pmc_dev *pmcdev, bool reset)
mutex_unlock(&pmcdev->lock);
}

-static int pmc_core_slps0_dbg_show(struct seq_file *s, void *unused)
+static void pmc_core_slps0_display(struct pmc_dev *pmcdev, struct device *dev,
+ struct seq_file *s)
{
- struct pmc_dev *pmcdev = s->private;
const struct pmc_bit_map **maps = pmcdev->map->slps0_dbg_maps;
const struct pmc_bit_map *map;
- int offset;
+ int offset = pmcdev->map->slps0_dbg_offset;
u32 data;

- pmc_core_slps0_dbg_latch(pmcdev, false);
- offset = pmcdev->map->slps0_dbg_offset;
while (*maps) {
map = *maps;
data = pmc_core_reg_read(pmcdev, offset);
offset += 4;
while (map->name) {
- seq_printf(s, "SLP_S0_DBG: %-32s\tState: %s\n",
- map->name,
- data & map->bit_mask ?
- "Yes" : "No");
+ if (dev)
+ dev_dbg(dev, "SLP_S0_DBG: %-32s\tState: %s\n",
+ map->name,
+ data & map->bit_mask ? "Yes" : "No");
+ if (s)
+ seq_printf(s, "SLP_S0_DBG: %-32s\tState: %s\n",
+ map->name,
+ data & map->bit_mask ? "Yes" : "No");
++map;
}
++maps;
}
+}
+
+static int pmc_core_slps0_dbg_show(struct seq_file *s, void *unused)
+{
+ struct pmc_dev *pmcdev = s->private;
+
+ pmc_core_slps0_dbg_latch(pmcdev, false);
+ pmc_core_slps0_display(pmcdev, NULL, s);
pmc_core_slps0_dbg_latch(pmcdev, true);
+
return 0;
}
DEFINE_SHOW_ATTRIBUTE(pmc_core_slps0_dbg);
@@ -1262,10 +1273,6 @@ static inline bool pmc_core_is_s0ix_failed(struct pmc_dev *pmcdev)
static int pmc_core_resume(struct device *dev)
{
struct pmc_dev *pmcdev = dev_get_drvdata(dev);
- const struct pmc_bit_map **maps = pmcdev->map->slps0_dbg_maps;
- int offset = pmcdev->map->slps0_dbg_offset;
- const struct pmc_bit_map *map;
- u32 data;

if (!pmcdev->check_counters)
return 0;
@@ -1283,18 +1290,9 @@ static int pmc_core_resume(struct device *dev)
/* The real interesting case - S0ix failed - lets ask PMC why. */
dev_warn(dev, "CPU did not enter SLP_S0!!! (S0ix cnt=%llu)\n",
pmcdev->s0ix_counter);
- while (*maps) {
- map = *maps;
- data = pmc_core_reg_read(pmcdev, offset);
- offset += 4;
- while (map->name) {
- dev_dbg(dev, "SLP_S0_DBG: %-32s\tState: %s\n",
- map->name,
- data & map->bit_mask ? "Yes" : "No");
- map++;
- }
- maps++;
- }
+ if (pmcdev->map->slps0_dbg_maps)
+ pmc_core_slps0_display(pmcdev, dev, NULL);
+
return 0;
}

--
2.17.1

2020-01-24 21:00:22

by Kammela, Gayatri

[permalink] [raw]
Subject: [PATCH v1 5/7] platform/x86: intel_pmc_core: Add an additional parameter to pmc_core_lpm_display()

Add a device pointer of type struct device as an additional parameter to
pmc_core_lpm_display(), so that the driver can re-use it to dump the
debug registers in resume for an S0ix failure.

Cc: Srinivas Pandruvada <[email protected]>
Cc: Andy Shevchenko <[email protected]>
Cc: David Box <[email protected]>
Signed-off-by: Gayatri Kammela <[email protected]>
---
drivers/platform/x86/intel_pmc_core.c | 24 ++++++++++++++++++------
1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c
index 338607b0a4e6..0018fdd0194b 100644
--- a/drivers/platform/x86/intel_pmc_core.c
+++ b/drivers/platform/x86/intel_pmc_core.c
@@ -972,8 +972,9 @@ static int pmc_core_substate_res_show(struct seq_file *s, void *unused)
}
DEFINE_SHOW_ATTRIBUTE(pmc_core_substate_res);

-static void pmc_core_lpm_display(struct pmc_dev *pmcdev, struct seq_file *s,
- u32 offset, const char *str,
+static void pmc_core_lpm_display(struct pmc_dev *pmcdev, struct device *dev,
+ struct seq_file *s, u32 offset,
+ const char *str,
const struct pmc_bit_map **maps)
{
u32 lpm_regs[ARRAY_SIZE(tgl_lpm_maps)-1];
@@ -985,11 +986,22 @@ static void pmc_core_lpm_display(struct pmc_dev *pmcdev, struct seq_file *s,
}

for (idx = 0; maps[idx]; idx++) {
- seq_printf(s, "\nLPM_%s_%d:\t0x%x\n", str, idx, lpm_regs[idx]);
+ if (dev)
+ dev_dbg(dev, "\nLPM_%s_%d:\t0x%x\n", str, idx,
+ lpm_regs[idx]);
+ if (s)
+ seq_printf(s, "\nLPM_%s_%d:\t0x%x\n", str, idx,
+ lpm_regs[idx]);
for (index = 0; maps[idx][index].name && index < len; index++) {
bit_mask = maps[idx][index].bit_mask;
- seq_printf(s, "%-30s %-30d\n", maps[idx][index].name,
- lpm_regs[idx] & bit_mask ? 1 : 0);
+ if (dev)
+ dev_dbg(dev, "%-30s %-30d\n",
+ maps[idx][index].name,
+ lpm_regs[idx] & bit_mask ? 1 : 0);
+ if (s)
+ seq_printf(s, "%-30s %-30d\n",
+ maps[idx][index].name,
+ lpm_regs[idx] & bit_mask ? 1 : 0);
}
}
}
@@ -1000,7 +1012,7 @@ static int pmc_core_substate_sts_regs_show(struct seq_file *s, void *unused)
const struct pmc_bit_map **maps = pmcdev->map->lpm_sts;
u32 offset = pmcdev->map->lpm_status_offset;

- pmc_core_lpm_display(pmcdev, s, offset, "STATUS", maps);
+ pmc_core_lpm_display(pmcdev, NULL, s, offset, "STATUS", maps);

return 0;
}
--
2.17.1

2020-01-24 21:00:22

by Kammela, Gayatri

[permalink] [raw]
Subject: [PATCH v1 7/7] platform/x86: intel_pmc_core: Add debugfs support to access live status registers

Just like status registers, Tiger Lake has another set of 6 registers
that help with status of the low power mode requirements. They are
latched on every PC10 entry/exit and S0ix.y entry/exit as well.

Though status and live status registers show the status of same list
of requirements, live status registers show the status of the low power
mode requirements at the time of reading.

Cc: Srinivas Pandruvada <[email protected]>
Cc: Andy Shevchenko <[email protected]>
Cc: David E. Box <[email protected]>
Signed-off-by: Gayatri Kammela <[email protected]>
---
drivers/platform/x86/intel_pmc_core.c | 19 +++++++++++++++++++
drivers/platform/x86/intel_pmc_core.h | 2 ++
2 files changed, 21 insertions(+)

diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c
index 92c9840b5029..d583cd5adb31 100644
--- a/drivers/platform/x86/intel_pmc_core.c
+++ b/drivers/platform/x86/intel_pmc_core.c
@@ -570,6 +570,7 @@ static const struct pmc_reg_map tgl_reg_map = {
.lpm_residency_offset = TGL_LPM_RESIDENCY_OFFSET,
.lpm_sts = tgl_lpm_maps,
.lpm_status_offset = TGL_LPM_STATUS_OFFSET,
+ .lpm_live_status_offset = TGL_LPM_LIVE_STATUS_OFFSET,
};

static inline u8 pmc_core_reg_read_byte(struct pmc_dev *pmcdev, int offset)
@@ -1018,6 +1019,18 @@ static int pmc_core_substate_sts_regs_show(struct seq_file *s, void *unused)
}
DEFINE_SHOW_ATTRIBUTE(pmc_core_substate_sts_regs);

+static int pmc_core_substate_l_sts_regs_show(struct seq_file *s, void *unused)
+{
+ struct pmc_dev *pmcdev = s->private;
+ const struct pmc_bit_map **maps = pmcdev->map->lpm_sts;
+ u32 offset = pmcdev->map->lpm_live_status_offset;
+
+ pmc_core_lpm_display(pmcdev, NULL, s, offset, "LIVE_STATUS", maps);
+
+ return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(pmc_core_substate_l_sts_regs);
+
static int pmc_core_pkgc_show(struct seq_file *s, void *unused)
{
struct pmc_dev *pmcdev = s->private;
@@ -1095,6 +1108,12 @@ static void pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
pmcdev->dbgfs_dir, pmcdev,
&pmc_core_substate_sts_regs_fops);
}
+
+ if (pmcdev->map->lpm_status_offset) {
+ debugfs_create_file("substate_live_status_registers", 0444,
+ pmcdev->dbgfs_dir, pmcdev,
+ &pmc_core_substate_l_sts_regs_fops);
+ }
}
#else
static inline void pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
diff --git a/drivers/platform/x86/intel_pmc_core.h b/drivers/platform/x86/intel_pmc_core.h
index 3fdf4735c56f..1bbdffe80bde 100644
--- a/drivers/platform/x86/intel_pmc_core.h
+++ b/drivers/platform/x86/intel_pmc_core.h
@@ -196,6 +196,7 @@ enum ppfear_regs {

/* Tigerlake Low Power Mode debug registers */
#define TGL_LPM_STATUS_OFFSET 0x1C3C
+#define TGL_LPM_LIVE_STATUS_OFFSET 0x1C5C

const char *lpm_modes[] = {
"S0i2.0",
@@ -257,6 +258,7 @@ struct pmc_reg_map {
const u32 lpm_en_offset;
const u32 lpm_residency_offset;
const u32 lpm_status_offset;
+ const u32 lpm_live_status_offset;
};

/**
--
2.17.1

2020-01-24 21:01:13

by Kammela, Gayatri

[permalink] [raw]
Subject: [PATCH v1 4/7] platform/x86: intel_pmc_core: Remove slp_s0 attributes from tgl_reg_map

If platforms such as Tiger Lake has sub-states of S0ix, then both
slp_s0_debug_status and slp_s0_dbg_latch entries become invalid. Thus,
remove slp_s0_offset and slp_s0_dbg_maps attributes from tgl_reg_map, so
that both the entries are not created.

Cc: Srinivas Pandruvada <[email protected]>
Cc: Andy Shevchenko <[email protected]>
Cc: David Box <[email protected]>
Signed-off-by: Gayatri Kammela <[email protected]>
---
drivers/platform/x86/intel_pmc_core.c | 2 --
1 file changed, 2 deletions(-)

diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c
index f52348edab57..338607b0a4e6 100644
--- a/drivers/platform/x86/intel_pmc_core.c
+++ b/drivers/platform/x86/intel_pmc_core.c
@@ -556,8 +556,6 @@ static const struct pmc_bit_map *tgl_lpm_maps[] = {

static const struct pmc_reg_map tgl_reg_map = {
.pfear_sts = ext_tgl_pfear_map,
- .slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET,
- .slps0_dbg_maps = cnp_slps0_dbg_maps,
.ltr_show_sts = cnp_ltr_show_map,
.msr_sts = msr_map,
.slps0_dbg_offset = CNP_PMC_SLPS0_DBG_OFFSET,
--
2.17.1

2020-01-24 21:01:23

by Kammela, Gayatri

[permalink] [raw]
Subject: [PATCH v1 6/7] platform/x86: intel_pmc_core: Dump low power status registers on an S0ix.y failure

Platforms prior to Tiger Lake has no sub-states of S0ix and accessing
device PM states that are latched whenever there is a PC10 entry is
possible with the help of slp_s0_debug_status and slp_s0_dbg_latch
debugfs entries.

If a platform has sub-states of S0ix, no such entries are created.
Hence, dump low power status registers on resume When any attempt to
enter any low power state was unsuccessful.

Cc: Srinivas Pandruvada <[email protected]>
Cc: Andy Shevchenko <[email protected]>
Cc: David Box <[email protected]>
Suggested-by: David Box <[email protected]>
Signed-off-by: Gayatri Kammela <[email protected]>
---
drivers/platform/x86/intel_pmc_core.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c
index 0018fdd0194b..92c9840b5029 100644
--- a/drivers/platform/x86/intel_pmc_core.c
+++ b/drivers/platform/x86/intel_pmc_core.c
@@ -1283,6 +1283,8 @@ static inline bool pmc_core_is_s0ix_failed(struct pmc_dev *pmcdev)
static int pmc_core_resume(struct device *dev)
{
struct pmc_dev *pmcdev = dev_get_drvdata(dev);
+ const struct pmc_bit_map **maps = pmcdev->map->lpm_sts;
+ int offset = pmcdev->map->lpm_status_offset;

if (!pmcdev->check_counters)
return 0;
@@ -1302,6 +1304,8 @@ static int pmc_core_resume(struct device *dev)
pmcdev->s0ix_counter);
if (pmcdev->map->slps0_dbg_maps)
pmc_core_slps0_display(pmcdev, dev, NULL);
+ if (pmcdev->map->lpm_sts)
+ pmc_core_lpm_display(pmcdev, dev, NULL, "STATUS", offset, maps);

return 0;
}
--
2.17.1

2020-01-27 11:19:28

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH v1 0/7] platform/x86: intel_pmc_core: Add debugfs entries

On Fri, Jan 24, 2020 at 10:59 PM Gayatri Kammela
<[email protected]> wrote:
>
> Hi,
>
> Tiger Lake platform supports 8 sub-states/low power modes of S0ix. Add
> debugfs entries to pmc_core driver to access low power mode registers
> and residencies.
>
> Patch 1: Add debugfs entry to access sub-state residencies
> Patch 2: Add debugfs entry for low power mode status registers
> Patch 3: Refactor the driver by removing redundant code
> Patch 4: Remove slp_s0 attributes from tgl_reg_map
> Patch 5: Add an additional parameter to pmc_core_lpm_display_map()
> Patch 6: Dump low power status registers on an S0ix.y failure
> Patch 7: Add debugfs support to access live status registers

It doesn't apply to our for-next branch.

>
> Gayatri Kammela (7):
> platform/x86: intel_pmc_core: Add debugfs entry to access sub-state
> residencies
> platform/x86: intel_pmc_core: Add debugfs entry for low power mode
> status registers
> platform/x86: intel_pmc_core: Refactor the driver by removing
> redundant code
> platform/x86: intel_pmc_core: Remove slp_s0 attributes from
> tgl_reg_map
> platform/x86: intel_pmc_core: Add an additional parameter to
> pmc_core_lpm_display()
> platform/x86: intel_pmc_core: Dump low power status registers on an
> S0ix.y failure
> platform/x86: intel_pmc_core: Add debugfs support to access live
> status registers
>
> drivers/platform/x86/intel_pmc_core.c | 301 +++++++++++++++++++++++---
> drivers/platform/x86/intel_pmc_core.h | 28 +++
> 2 files changed, 302 insertions(+), 27 deletions(-)
>
> Cc: Srinivas Pandruvada <[email protected]>
> Cc: Andy Shevchenko <[email protected]>
> Cc: David Box <[email protected]>
> --
> 2.17.1
>


--
With Best Regards,
Andy Shevchenko

2020-01-27 18:03:57

by Kammela, Gayatri

[permalink] [raw]
Subject: RE: [PATCH v1 0/7] platform/x86: intel_pmc_core: Add debugfs entries



> -----Original Message-----
> From: Andy Shevchenko <[email protected]>
> Sent: Monday, January 27, 2020 2:49 AM
> To: Kammela, Gayatri <[email protected]>
> Cc: Platform Driver <[email protected]>; Linux Kernel
> Mailing List <[email protected]>; Somayaji, Vishwanath
> <[email protected]>; Darren Hart <[email protected]>;
> Westerberg, Mika <[email protected]>; Peter Zijlstra (Intel)
> <[email protected]>; Prestopine, Charles D
> <[email protected]>; Pandruvada, Srinivas
> <[email protected]>; Andy Shevchenko
> <[email protected]>; Box, David E
> <[email protected]>
> Subject: Re: [PATCH v1 0/7] platform/x86: intel_pmc_core: Add debugfs
> entries
>
> On Fri, Jan 24, 2020 at 10:59 PM Gayatri Kammela
> <[email protected]> wrote:
> >
> > Hi,
> >
> > Tiger Lake platform supports 8 sub-states/low power modes of S0ix. Add
> > debugfs entries to pmc_core driver to access low power mode registers
> > and residencies.
> >
> > Patch 1: Add debugfs entry to access sub-state residencies Patch 2:
> > Add debugfs entry for low power mode status registers Patch 3:
> > Refactor the driver by removing redundant code Patch 4: Remove slp_s0
> > attributes from tgl_reg_map Patch 5: Add an additional parameter to
> > pmc_core_lpm_display_map() Patch 6: Dump low power status registers on
> > an S0ix.y failure Patch 7: Add debugfs support to access live status
> > registers
>
> It doesn't apply to our for-next branch.
Sorry to hear that. I've rebased the series on mainline 5.5-rc7. Should I rebase it on for-next branch?
>
> >
> > Gayatri Kammela (7):
> > platform/x86: intel_pmc_core: Add debugfs entry to access sub-state
> > residencies
> > platform/x86: intel_pmc_core: Add debugfs entry for low power mode
> > status registers
> > platform/x86: intel_pmc_core: Refactor the driver by removing
> > redundant code
> > platform/x86: intel_pmc_core: Remove slp_s0 attributes from
> > tgl_reg_map
> > platform/x86: intel_pmc_core: Add an additional parameter to
> > pmc_core_lpm_display()
> > platform/x86: intel_pmc_core: Dump low power status registers on an
> > S0ix.y failure
> > platform/x86: intel_pmc_core: Add debugfs support to access live
> > status registers
> >
> > drivers/platform/x86/intel_pmc_core.c | 301
> > +++++++++++++++++++++++--- drivers/platform/x86/intel_pmc_core.h |
> > 28 +++
> > 2 files changed, 302 insertions(+), 27 deletions(-)
> >
> > Cc: Srinivas Pandruvada <[email protected]>
> > Cc: Andy Shevchenko <[email protected]>
> > Cc: David Box <[email protected]>
> > --
> > 2.17.1
> >
>
>
> --
> With Best Regards,
> Andy Shevchenko

2020-01-27 19:01:22

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH v1 0/7] platform/x86: intel_pmc_core: Add debugfs entries

On Mon, Jan 27, 2020 at 8:03 PM Kammela, Gayatri
<[email protected]> wrote:

> > It doesn't apply to our for-next branch.
> Sorry to hear that. I've rebased the series on mainline 5.5-rc7. Should I rebase it on for-next branch?

You should always base your branch on the for-next (whatever it's
being called) of the subsystem your series against of.

--
With Best Regards,
Andy Shevchenko

2020-02-04 04:03:21

by Kammela, Gayatri

[permalink] [raw]
Subject: RE: [PATCH v1 0/7] platform/x86: intel_pmc_core: Add debugfs entries

> -----Original Message-----
> From: Andy Shevchenko <[email protected]>
> Sent: Monday, January 27, 2020 11:00 AM
> To: Kammela, Gayatri <[email protected]>
> Cc: Platform Driver <[email protected]>; Linux Kernel
> Mailing List <[email protected]>; Somayaji, Vishwanath
> <[email protected]>; Darren Hart <[email protected]>;
> Westerberg, Mika <[email protected]>; Peter Zijlstra (Intel)
> <[email protected]>; Prestopine, Charles D
> <[email protected]>; Pandruvada, Srinivas
> <[email protected]>; Andy Shevchenko
> <[email protected]>; Box, David E
> <[email protected]>
> Subject: Re: [PATCH v1 0/7] platform/x86: intel_pmc_core: Add debugfs
> entries
>
> On Mon, Jan 27, 2020 at 8:03 PM Kammela, Gayatri
> <[email protected]> wrote:
>
> > > It doesn't apply to our for-next branch.
> > Sorry to hear that. I've rebased the series on mainline 5.5-rc7. Should I
> rebase it on for-next branch?
>
> You should always base your branch on the for-next (whatever it's being
> called) of the subsystem your series against of.

Hi Andy,

The current series has a dependency on Tiger Lake and Elkhart Lake patche which is merged in to mainline.

(554f269f0f38 platform/x86: intel_pmc_core: Add Intel Elkhart Lake support
49a437941c3f platform/x86: intel_pmc_core: Add Intel Tiger Lake support
6268c0b278b5 platform/x86: intel_pmc_core: Make debugfs entry for pch_ip_power_gating_status conditional
e39854781830 platform/x86: intel_pmc_core: Create platform dependent bitmap structs
b1cb33dae414 platform/x86: intel_pmc_core: Clean up: Remove comma after the termination line)

But they are not available in for-next branch. I am confused, how that could be the case. For me to base the current series on for-next branch, the dependency patch series should be available in for-next branch.

>
> --
> With Best Regards,
> Andy Shevchenko

2020-02-04 11:35:27

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH v1 0/7] platform/x86: intel_pmc_core: Add debugfs entries

On Tue, Feb 04, 2020 at 04:00:43AM +0000, Kammela, Gayatri wrote:
> > -----Original Message-----
> > From: Andy Shevchenko <[email protected]>
> > Sent: Monday, January 27, 2020 11:00 AM
> > To: Kammela, Gayatri <[email protected]>
> > Cc: Platform Driver <[email protected]>; Linux Kernel
> > Mailing List <[email protected]>; Somayaji, Vishwanath
> > <[email protected]>; Darren Hart <[email protected]>;
> > Westerberg, Mika <[email protected]>; Peter Zijlstra (Intel)
> > <[email protected]>; Prestopine, Charles D
> > <[email protected]>; Pandruvada, Srinivas
> > <[email protected]>; Andy Shevchenko
> > <[email protected]>; Box, David E
> > <[email protected]>
> > Subject: Re: [PATCH v1 0/7] platform/x86: intel_pmc_core: Add debugfs
> > entries
> >
> > On Mon, Jan 27, 2020 at 8:03 PM Kammela, Gayatri
> > <[email protected]> wrote:
> >
> > > > It doesn't apply to our for-next branch.
> > > Sorry to hear that. I've rebased the series on mainline 5.5-rc7. Should I
> > rebase it on for-next branch?
> >
> > You should always base your branch on the for-next (whatever it's being
> > called) of the subsystem your series against of.
>
> Hi Andy,
>
> The current series has a dependency on Tiger Lake and Elkhart Lake patche which is merged in to mainline.
>
> (554f269f0f38 platform/x86: intel_pmc_core: Add Intel Elkhart Lake support
> 49a437941c3f platform/x86: intel_pmc_core: Add Intel Tiger Lake support
> 6268c0b278b5 platform/x86: intel_pmc_core: Make debugfs entry for pch_ip_power_gating_status conditional
> e39854781830 platform/x86: intel_pmc_core: Create platform dependent bitmap structs
> b1cb33dae414 platform/x86: intel_pmc_core: Clean up: Remove comma after the termination line)
>
> But they are not available in for-next branch. I am confused, how that could be the case. For me to base the current series on for-next branch, the dependency patch series should be available in for-next branch.

I'm wondering how did you check it?
The branch location is in this [1] tree.

[1]: http://git.infradead.org/linux-platform-drivers-x86.git

--
With Best Regards,
Andy Shevchenko


2020-02-04 23:13:30

by Kammela, Gayatri

[permalink] [raw]
Subject: RE: [PATCH v1 0/7] platform/x86: intel_pmc_core: Add debugfs entries

> > > > > It doesn't apply to our for-next branch.
> > > > Sorry to hear that. I've rebased the series on mainline 5.5-rc7.
> > > > Should I
> > > rebase it on for-next branch?
> > >
> > > You should always base your branch on the for-next (whatever it's
> > > being
> > > called) of the subsystem your series against of.
> >
> > Hi Andy,
> >
> > The current series has a dependency on Tiger Lake and Elkhart Lake patche
> which is merged in to mainline.
> >
> > (554f269f0f38 platform/x86: intel_pmc_core: Add Intel Elkhart Lake
> > support 49a437941c3f platform/x86: intel_pmc_core: Add Intel Tiger
> > Lake support
> > 6268c0b278b5 platform/x86: intel_pmc_core: Make debugfs entry for
> > pch_ip_power_gating_status conditional
> > e39854781830 platform/x86: intel_pmc_core: Create platform dependent
> > bitmap structs
> > b1cb33dae414 platform/x86: intel_pmc_core: Clean up: Remove comma
> > after the termination line)
> >
> > But they are not available in for-next branch. I am confused, how that could
> be the case. For me to base the current series on for-next branch, the
> dependency patch series should be available in for-next branch.
>
> I'm wondering how did you check it?
> The branch location is in this [1] tree.

Thank you for your patience Andy. I apologize for the mishap as I was checking in the wrong tree. I have rebased the series on for-next branch on right tree this time and sent v2.

>
> [1]: http://git.infradead.org/linux-platform-drivers-x86.git
>
> --
> With Best Regards,
> Andy Shevchenko
>

2020-02-05 09:10:55

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH v1 0/7] platform/x86: intel_pmc_core: Add debugfs entries

On Wed, Feb 5, 2020 at 1:11 AM Kammela, Gayatri
<[email protected]> wrote:

...

> > I'm wondering how did you check it?
> > The branch location is in this [1] tree.
>
> Thank you for your patience Andy. I apologize for the mishap as I was checking in the wrong tree. I have rebased the series on for-next branch on right tree this time and sent v2.

No worries, thanks for the update!

> > [1]: http://git.infradead.org/linux-platform-drivers-x86.git

--
With Best Regards,
Andy Shevchenko