aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>2015-05-06 15:15:54 -0400
committerIngo Molnar <mingo@kernel.org>2015-05-07 05:18:27 -0400
commit956079e081427fe0c929eb284ab7e39f9b8e2023 (patch)
treee9b22da8b1fa79b0480f2b8d21e3c6da696f3c5c
parent1222e564cf4394af0b3c5e8a73330b20862c068b (diff)
x86/platform/atom/punit: Add Punit device state debug driver
The patch adds a debug driver, which dumps the power states of all the North complex (NC) devices. This debug interface is useful to figure out the devices, which blocks the S0ix transitions on the platform. This is extremely useful during enabling PM on customer platforms and derivatives. This submission is based on the submission from Mahesh Kumar P: https://lkml.org/lkml/2014/11/5/367 Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Cc: Borislav Petkov <bp@alien8.de> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Mahesh Kumar P <mahesh.kumar.p@intel.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: pebolle@tiscali.nl Link: http://lkml.kernel.org/r/1430939754-6900-2-git-send-email-srinivas.pandruvada@linux.intel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/Kconfig.debug11
-rw-r--r--arch/x86/platform/Makefile1
-rw-r--r--arch/x86/platform/atom/Makefile1
-rw-r--r--arch/x86/platform/atom/punit_atom_debug.c183
4 files changed, 196 insertions, 0 deletions
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index 72484a645f05..a5973f851750 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -332,4 +332,15 @@ config X86_DEBUG_STATIC_CPU_HAS
332 332
333 If unsure, say N. 333 If unsure, say N.
334 334
335config PUNIT_ATOM_DEBUG
336 tristate "ATOM Punit debug driver"
337 select DEBUG_FS
338 select IOSF_MBI
339 ---help---
340 This is a debug driver, which gets the power states
341 of all Punit North Complex devices. The power states of
342 each device is exposed as part of the debugfs interface.
343 The current power state can be read from
344 /sys/kernel/debug/punit_atom/dev_power_state
345
335endmenu 346endmenu
diff --git a/arch/x86/platform/Makefile b/arch/x86/platform/Makefile
index a62e0be3a2f1..f1a6c8e86ddd 100644
--- a/arch/x86/platform/Makefile
+++ b/arch/x86/platform/Makefile
@@ -1,4 +1,5 @@
1# Platform specific code goes here 1# Platform specific code goes here
2obj-y += atom/
2obj-y += ce4100/ 3obj-y += ce4100/
3obj-y += efi/ 4obj-y += efi/
4obj-y += geode/ 5obj-y += geode/
diff --git a/arch/x86/platform/atom/Makefile b/arch/x86/platform/atom/Makefile
new file mode 100644
index 000000000000..0a3a40cbc794
--- /dev/null
+++ b/arch/x86/platform/atom/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_PUNIT_ATOM_DEBUG) += punit_atom_debug.o
diff --git a/arch/x86/platform/atom/punit_atom_debug.c b/arch/x86/platform/atom/punit_atom_debug.c
new file mode 100644
index 000000000000..5ca8ead91579
--- /dev/null
+++ b/arch/x86/platform/atom/punit_atom_debug.c
@@ -0,0 +1,183 @@
1/*
2 * Intel SOC Punit device state debug driver
3 * Punit controls power management for North Complex devices (Graphics
4 * blocks, Image Signal Processing, video processing, display, DSP etc.)
5 *
6 * Copyright (c) 2015, Intel Corporation.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 */
18
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/device.h>
22#include <linux/debugfs.h>
23#include <linux/seq_file.h>
24#include <linux/io.h>
25#include <asm/cpu_device_id.h>
26#include <asm/iosf_mbi.h>
27
28/* Side band Interface port */
29#define PUNIT_PORT 0x04
30/* Power gate status reg */
31#define PWRGT_STATUS 0x61
32/* Subsystem config/status Video processor */
33#define VED_SS_PM0 0x32
34/* Subsystem config/status ISP (Image Signal Processor) */
35#define ISP_SS_PM0 0x39
36/* Subsystem config/status Input/output controller */
37#define MIO_SS_PM 0x3B
38/* Shift bits for getting status for video, isp and i/o */
39#define SSS_SHIFT 24
40/* Shift bits for getting status for graphics rendering */
41#define RENDER_POS 0
42/* Shift bits for getting status for media control */
43#define MEDIA_POS 2
44/* Shift bits for getting status for Valley View/Baytrail display */
45#define VLV_DISPLAY_POS 6
46/* Subsystem config/status display for Cherry Trail SOC */
47#define CHT_DSP_SSS 0x36
48/* Shift bits for getting status for display */
49#define CHT_DSP_SSS_POS 16
50
51struct punit_device {
52 char *name;
53 int reg;
54 int sss_pos;
55};
56
57static const struct punit_device punit_device_byt[] = {
58 { "GFX RENDER", PWRGT_STATUS, RENDER_POS },
59 { "GFX MEDIA", PWRGT_STATUS, MEDIA_POS },
60 { "DISPLAY", PWRGT_STATUS, VLV_DISPLAY_POS },
61 { "VED", VED_SS_PM0, SSS_SHIFT },
62 { "ISP", ISP_SS_PM0, SSS_SHIFT },
63 { "MIO", MIO_SS_PM, SSS_SHIFT },
64 { NULL }
65};
66
67static const struct punit_device punit_device_cht[] = {
68 { "GFX RENDER", PWRGT_STATUS, RENDER_POS },
69 { "GFX MEDIA", PWRGT_STATUS, MEDIA_POS },
70 { "DISPLAY", CHT_DSP_SSS, CHT_DSP_SSS_POS },
71 { "VED", VED_SS_PM0, SSS_SHIFT },
72 { "ISP", ISP_SS_PM0, SSS_SHIFT },
73 { "MIO", MIO_SS_PM, SSS_SHIFT },
74 { NULL }
75};
76
77static const char * const dstates[] = {"D0", "D0i1", "D0i2", "D0i3"};
78
79static int punit_dev_state_show(struct seq_file *seq_file, void *unused)
80{
81 u32 punit_pwr_status;
82 struct punit_device *punit_devp = seq_file->private;
83 int index;
84 int status;
85
86 seq_puts(seq_file, "\n\nPUNIT NORTH COMPLEX DEVICES :\n");
87 while (punit_devp->name) {
88 status = iosf_mbi_read(PUNIT_PORT, BT_MBI_PMC_READ,
89 punit_devp->reg,
90 &punit_pwr_status);
91 if (status) {
92 seq_printf(seq_file, "%9s : Read Failed\n",
93 punit_devp->name);
94 } else {
95 index = (punit_pwr_status >> punit_devp->sss_pos) & 3;
96 seq_printf(seq_file, "%9s : %s\n", punit_devp->name,
97 dstates[index]);
98 }
99 punit_devp++;
100 }
101
102 return 0;
103}
104
105static int punit_dev_state_open(struct inode *inode, struct file *file)
106{
107 return single_open(file, punit_dev_state_show, inode->i_private);
108}
109
110static const struct file_operations punit_dev_state_ops = {
111 .open = punit_dev_state_open,
112 .read = seq_read,
113 .llseek = seq_lseek,
114 .release = single_release,
115};
116
117static struct dentry *punit_dbg_file;
118
119static int punit_dbgfs_register(struct punit_device *punit_device)
120{
121 static struct dentry *dev_state;
122
123 punit_dbg_file = debugfs_create_dir("punit_atom", NULL);
124 if (!punit_dbg_file)
125 return -ENXIO;
126
127 dev_state = debugfs_create_file("dev_power_state", S_IFREG | S_IRUGO,
128 punit_dbg_file, punit_device,
129 &punit_dev_state_ops);
130 if (!dev_state) {
131 pr_err("punit_dev_state register failed\n");
132 debugfs_remove(punit_dbg_file);
133 return -ENXIO;
134 }
135
136 return 0;
137}
138
139static void punit_dbgfs_unregister(void)
140{
141 debugfs_remove_recursive(punit_dbg_file);
142}
143
144#define ICPU(model, drv_data) \
145 { X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT,\
146 (kernel_ulong_t)&drv_data }
147
148static const struct x86_cpu_id intel_punit_cpu_ids[] = {
149 ICPU(55, punit_device_byt), /* Valleyview, Bay Trail */
150 ICPU(76, punit_device_cht), /* Braswell, Cherry Trail */
151 {}
152};
153
154MODULE_DEVICE_TABLE(x86cpu, intel_punit_cpu_ids);
155
156static int __init punit_atom_debug_init(void)
157{
158 const struct x86_cpu_id *id;
159 int ret;
160
161 id = x86_match_cpu(intel_punit_cpu_ids);
162 if (!id)
163 return -ENODEV;
164
165 ret = punit_dbgfs_register((struct punit_device *)id->driver_data);
166 if (ret < 0)
167 return ret;
168
169 return 0;
170}
171
172static void __exit punit_atom_debug_exit(void)
173{
174 punit_dbgfs_unregister();
175}
176
177module_init(punit_atom_debug_init);
178module_exit(punit_atom_debug_exit);
179
180MODULE_AUTHOR("Kumar P, Mahesh <mahesh.kumar.p@intel.com>");
181MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
182MODULE_DESCRIPTION("Driver for Punit devices states debugging");
183MODULE_LICENSE("GPL v2");