Skip to content

Commit

Permalink
x86: pmc_atom: Expose contents of PSS
Browse files Browse the repository at this point in the history
The PSS register reflects the power state of each island on SoC. It would be
useful to know which of the islands is on or off at the momemnt.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Aubrey Li <aubrey.li@linux.intel.com>
Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Kumar P. Mahesh <mahesh.kumar.p@intel.com>
Link: http://lkml.kernel.org/r/1421253575-22509-6-git-send-email-andriy.shevchenko@linux.intel.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
  • Loading branch information
Andy Shevchenko authored and Thomas Gleixner committed Jan 20, 2015
1 parent 4b25f42 commit 0e15402
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 3 deletions.
22 changes: 22 additions & 0 deletions arch/x86/include/asm/pmc_atom.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,28 @@
/* Sleep state counter is in units of of 32us */
#define PMC_TMR_SHIFT 5

/* Power status of power islands */
#define PMC_PSS 0x98

#define PMC_PSS_BIT_GBE BIT(0)
#define PMC_PSS_BIT_SATA BIT(1)
#define PMC_PSS_BIT_HDA BIT(2)
#define PMC_PSS_BIT_SEC BIT(3)
#define PMC_PSS_BIT_PCIE BIT(4)
#define PMC_PSS_BIT_LPSS BIT(5)
#define PMC_PSS_BIT_LPE BIT(6)
#define PMC_PSS_BIT_DFX BIT(7)
#define PMC_PSS_BIT_USH_CTRL BIT(8)
#define PMC_PSS_BIT_USH_SUS BIT(9)
#define PMC_PSS_BIT_USH_VCCS BIT(10)
#define PMC_PSS_BIT_USH_VCCA BIT(11)
#define PMC_PSS_BIT_OTG_CTRL BIT(12)
#define PMC_PSS_BIT_OTG_VCCS BIT(13)
#define PMC_PSS_BIT_OTG_VCCA_CLK BIT(14)
#define PMC_PSS_BIT_OTG_VCCA BIT(15)
#define PMC_PSS_BIT_USB BIT(16)
#define PMC_PSS_BIT_USB_SUS BIT(17)

/* These registers reflect D3 status of functions */
#define PMC_D3_STS_0 0xA0

Expand Down
61 changes: 58 additions & 3 deletions arch/x86/kernel/pmc_atom.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ struct pmc_dev {
static struct pmc_dev pmc_device;
static u32 acpi_base_addr;

struct pmc_dev_map {
struct pmc_bit_map {
const char *name;
u32 bit_mask;
};

static const struct pmc_dev_map dev_map[] = {
static const struct pmc_bit_map dev_map[] = {
{"0 - LPSS1_F0_DMA", BIT_LPSS1_F0_DMA},
{"1 - LPSS1_F1_PWM1", BIT_LPSS1_F1_PWM1},
{"2 - LPSS1_F2_PWM2", BIT_LPSS1_F2_PWM2},
Expand Down Expand Up @@ -80,6 +80,27 @@ static const struct pmc_dev_map dev_map[] = {
{"35 - DFX", BIT_DFX},
};

static const struct pmc_bit_map pss_map[] = {
{"0 - GBE", PMC_PSS_BIT_GBE},
{"1 - SATA", PMC_PSS_BIT_SATA},
{"2 - HDA", PMC_PSS_BIT_HDA},
{"3 - SEC", PMC_PSS_BIT_SEC},
{"4 - PCIE", PMC_PSS_BIT_PCIE},
{"5 - LPSS", PMC_PSS_BIT_LPSS},
{"6 - LPE", PMC_PSS_BIT_LPE},
{"7 - DFX", PMC_PSS_BIT_DFX},
{"8 - USH_CTRL", PMC_PSS_BIT_USH_CTRL},
{"9 - USH_SUS", PMC_PSS_BIT_USH_SUS},
{"10 - USH_VCCS", PMC_PSS_BIT_USH_VCCS},
{"11 - USH_VCCA", PMC_PSS_BIT_USH_VCCA},
{"12 - OTG_CTRL", PMC_PSS_BIT_OTG_CTRL},
{"13 - OTG_VCCS", PMC_PSS_BIT_OTG_VCCS},
{"14 - OTG_VCCA_CLK", PMC_PSS_BIT_OTG_VCCA_CLK},
{"15 - OTG_VCCA", PMC_PSS_BIT_OTG_VCCA},
{"16 - USB", PMC_PSS_BIT_USB},
{"17 - USB_SUS", PMC_PSS_BIT_USB_SUS},
};

static inline u32 pmc_reg_read(struct pmc_dev *pmc, int reg_offset)
{
return readl(pmc->regmap + reg_offset);
Expand Down Expand Up @@ -167,6 +188,32 @@ static const struct file_operations pmc_dev_state_ops = {
.release = single_release,
};

static int pmc_pss_state_show(struct seq_file *s, void *unused)
{
struct pmc_dev *pmc = s->private;
u32 pss = pmc_reg_read(pmc, PMC_PSS);
int pss_index;

for (pss_index = 0; pss_index < ARRAY_SIZE(pss_map); pss_index++) {
seq_printf(s, "Island: %-32s\tState: %s\n",
pss_map[pss_index].name,
pss_map[pss_index].bit_mask & pss ? "Off" : "On");
}
return 0;
}

static int pmc_pss_state_open(struct inode *inode, struct file *file)
{
return single_open(file, pmc_pss_state_show, inode->i_private);
}

static const struct file_operations pmc_pss_state_ops = {
.open = pmc_pss_state_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};

static int pmc_sleep_tmr_show(struct seq_file *s, void *unused)
{
struct pmc_dev *pmc = s->private;
Expand Down Expand Up @@ -216,9 +263,17 @@ static int pmc_dbgfs_register(struct pmc_dev *pmc, struct pci_dev *pdev)
f = debugfs_create_file("dev_state", S_IFREG | S_IRUGO,
dir, pmc, &pmc_dev_state_ops);
if (!f) {
dev_err(&pdev->dev, "dev_states register failed\n");
dev_err(&pdev->dev, "dev_state register failed\n");
goto err;
}

f = debugfs_create_file("pss_state", S_IFREG | S_IRUGO,
dir, pmc, &pmc_pss_state_ops);
if (!f) {
dev_err(&pdev->dev, "pss_state register failed\n");
goto err;
}

f = debugfs_create_file("sleep_state", S_IFREG | S_IRUGO,
dir, pmc, &pmc_sleep_tmr_ops);
if (!f) {
Expand Down

0 comments on commit 0e15402

Please sign in to comment.