Blame view

arch/arm/mach-omap2/pm-debug.c 5.89 KB
8bd229492   Kevin Hilman   OMAP2/3: PM: push...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  /*
   * OMAP Power Management debug routines
   *
   * Copyright (C) 2005 Texas Instruments, Inc.
   * Copyright (C) 2006-2008 Nokia Corporation
   *
   * Written by:
   * Richard Woodruff <r-woodruff2@ti.com>
   * Tony Lindgren
   * Juha Yrjola
   * Amit Kucheria <amit.kucheria@nokia.com>
   * Igor Stoppa <igor.stoppa@nokia.com>
   * Jouni Hogander
   *
   * Based on pm.c for omap2
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
   */
  
  #include <linux/kernel.h>
331b93f41   Peter 'p2' De Schrijver   OMAP: PM: Add pm-...
23
  #include <linux/sched.h>
8bd229492   Kevin Hilman   OMAP2/3: PM: push...
24
25
26
  #include <linux/clk.h>
  #include <linux/err.h>
  #include <linux/io.h>
68d4778c7   Tero Kristo   OMAP: PM: Added s...
27
  #include <linux/module.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
28
  #include <linux/slab.h>
8bd229492   Kevin Hilman   OMAP2/3: PM: push...
29

ce491cf85   Tony Lindgren   omap: headers: Mo...
30
31
  #include <plat/clock.h>
  #include <plat/board.h>
72e06d087   Paul Walmsley   OMAP2+: powerdoma...
32
  #include "powerdomain.h"
1540f2140   Paul Walmsley   OMAP2+: clockdoma...
33
  #include "clockdomain.h"
86b0c1e3c   Santosh Shilimkar   omap: pm-debug: M...
34
  #include <plat/dmtimer.h>
6081dc348   Kevin Hilman   OMAP: PM noop: im...
35
  #include <plat/omap-pm.h>
8bd229492   Kevin Hilman   OMAP2/3: PM: push...
36

59fb659b0   Paul Walmsley   OMAP2/3: PRCM: sp...
37
38
  #include "cm2xxx_3xxx.h"
  #include "prm2xxx_3xxx.h"
8bd229492   Kevin Hilman   OMAP2/3: PM: push...
39
  #include "pm.h"
6cdee9125   Thara Gopinath   OMAP: PM debugfs ...
40
  u32 enable_off_mode;
331b93f41   Peter 'p2' De Schrijver   OMAP: PM: Add pm-...
41
42
43
44
  
  #ifdef CONFIG_DEBUG_FS
  #include <linux/debugfs.h>
  #include <linux/seq_file.h>
331b93f41   Peter 'p2' De Schrijver   OMAP: PM: Add pm-...
45
  static int pm_dbg_init_done;
c8fb13d04   Russell King   OMAP: PM debug: f...
46
  static int pm_dbg_init(void);
6b34f9d4e   Sergio Aguirre   PM debug: Fix war...
47

331b93f41   Peter 'p2' De Schrijver   OMAP: PM: Add pm-...
48
49
50
51
  enum {
  	DEBUG_FILE_COUNTERS = 0,
  	DEBUG_FILE_TIMERS,
  };
2354eb5a9   Paul Walmsley   OMAP powerdomain/...
52
  static const char pwrdm_state_names[][PWRDM_MAX_PWRSTS] = {
331b93f41   Peter 'p2' De Schrijver   OMAP: PM: Add pm-...
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
  	"OFF",
  	"RET",
  	"INA",
  	"ON"
  };
  
  void pm_dbg_update_time(struct powerdomain *pwrdm, int prev)
  {
  	s64 t;
  
  	if (!pm_dbg_init_done)
  		return ;
  
  	/* Update timer for previous state */
  	t = sched_clock();
  
  	pwrdm->state_timer[prev] += t - pwrdm->timer;
  
  	pwrdm->timer = t;
  }
  
  static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user)
  {
  	struct seq_file *s = (struct seq_file *)user;
  
  	if (strcmp(clkdm->name, "emu_clkdm") == 0 ||
  		strcmp(clkdm->name, "wkup_clkdm") == 0 ||
  		strncmp(clkdm->name, "dpll", 4) == 0)
  		return 0;
  
  	seq_printf(s, "%s->%s (%d)", clkdm->name,
  			clkdm->pwrdm.ptr->name,
  			atomic_read(&clkdm->usecount));
  	seq_printf(s, "
  ");
  
  	return 0;
  }
  
  static int pwrdm_dbg_show_counter(struct powerdomain *pwrdm, void *user)
  {
  	struct seq_file *s = (struct seq_file *)user;
  	int i;
  
  	if (strcmp(pwrdm->name, "emu_pwrdm") == 0 ||
  		strcmp(pwrdm->name, "wkup_pwrdm") == 0 ||
  		strncmp(pwrdm->name, "dpll", 4) == 0)
  		return 0;
  
  	if (pwrdm->state != pwrdm_read_pwrst(pwrdm))
  		printk(KERN_ERR "pwrdm state mismatch(%s) %d != %d
  ",
  			pwrdm->name, pwrdm->state, pwrdm_read_pwrst(pwrdm));
  
  	seq_printf(s, "%s (%s)", pwrdm->name,
  			pwrdm_state_names[pwrdm->state]);
2354eb5a9   Paul Walmsley   OMAP powerdomain/...
109
  	for (i = 0; i < PWRDM_MAX_PWRSTS; i++)
331b93f41   Peter 'p2' De Schrijver   OMAP: PM: Add pm-...
110
111
  		seq_printf(s, ",%s:%d", pwrdm_state_names[i],
  			pwrdm->state_counter[i]);
cde08f81b   Thara Gopinath   OMAP3 PM: Adding ...
112
113
114
115
  	seq_printf(s, ",RET-LOGIC-OFF:%d", pwrdm->ret_logic_off_counter);
  	for (i = 0; i < pwrdm->banks; i++)
  		seq_printf(s, ",RET-MEMBANK%d-OFF:%d", i + 1,
  				pwrdm->ret_mem_off_counter[i]);
331b93f41   Peter 'p2' De Schrijver   OMAP: PM: Add pm-...
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
  	seq_printf(s, "
  ");
  
  	return 0;
  }
  
  static int pwrdm_dbg_show_timer(struct powerdomain *pwrdm, void *user)
  {
  	struct seq_file *s = (struct seq_file *)user;
  	int i;
  
  	if (strcmp(pwrdm->name, "emu_pwrdm") == 0 ||
  		strcmp(pwrdm->name, "wkup_pwrdm") == 0 ||
  		strncmp(pwrdm->name, "dpll", 4) == 0)
  		return 0;
  
  	pwrdm_state_switch(pwrdm);
  
  	seq_printf(s, "%s (%s)", pwrdm->name,
  		pwrdm_state_names[pwrdm->state]);
  
  	for (i = 0; i < 4; i++)
  		seq_printf(s, ",%s:%lld", pwrdm_state_names[i],
  			pwrdm->state_timer[i]);
  
  	seq_printf(s, "
  ");
  	return 0;
  }
  
  static int pm_dbg_show_counters(struct seq_file *s, void *unused)
  {
  	pwrdm_for_each(pwrdm_dbg_show_counter, s);
  	clkdm_for_each(clkdm_dbg_show_counter, s);
  
  	return 0;
  }
  
  static int pm_dbg_show_timers(struct seq_file *s, void *unused)
  {
  	pwrdm_for_each(pwrdm_dbg_show_timer, s);
  	return 0;
  }
  
  static int pm_dbg_open(struct inode *inode, struct file *file)
  {
  	switch ((int)inode->i_private) {
  	case DEBUG_FILE_COUNTERS:
  		return single_open(file, pm_dbg_show_counters,
  			&inode->i_private);
  	case DEBUG_FILE_TIMERS:
  	default:
  		return single_open(file, pm_dbg_show_timers,
  			&inode->i_private);
  	};
  }
  
  static const struct file_operations debug_fops = {
  	.open           = pm_dbg_open,
  	.read           = seq_read,
  	.llseek         = seq_lseek,
  	.release        = single_release,
  };
68d4778c7   Tero Kristo   OMAP: PM: Added s...
179
180
  static int pwrdm_suspend_get(void *data, u64 *val)
  {
6cdee9125   Thara Gopinath   OMAP: PM debugfs ...
181
182
183
184
  	int ret = -EINVAL;
  
  	if (cpu_is_omap34xx())
  		ret = omap3_pm_get_suspend_state((struct powerdomain *)data);
61b17d972   Roel Kluin   OMAP: omap3_pm_ge...
185
  	*val = ret;
68d4778c7   Tero Kristo   OMAP: PM: Added s...
186

61b17d972   Roel Kluin   OMAP: omap3_pm_ge...
187
  	if (ret >= 0)
68d4778c7   Tero Kristo   OMAP: PM: Added s...
188
189
190
191
192
193
  		return 0;
  	return *val;
  }
  
  static int pwrdm_suspend_set(void *data, u64 val)
  {
6cdee9125   Thara Gopinath   OMAP: PM debugfs ...
194
195
196
197
  	if (cpu_is_omap34xx())
  		return omap3_pm_set_suspend_state(
  			(struct powerdomain *)data, (int)val);
  	return -EINVAL;
68d4778c7   Tero Kristo   OMAP: PM: Added s...
198
199
200
201
202
203
204
  }
  
  DEFINE_SIMPLE_ATTRIBUTE(pwrdm_suspend_fops, pwrdm_suspend_get,
  			pwrdm_suspend_set, "%llu
  ");
  
  static int __init pwrdms_setup(struct powerdomain *pwrdm, void *dir)
331b93f41   Peter 'p2' De Schrijver   OMAP: PM: Add pm-...
205
206
207
  {
  	int i;
  	s64 t;
68d4778c7   Tero Kristo   OMAP: PM: Added s...
208
  	struct dentry *d;
331b93f41   Peter 'p2' De Schrijver   OMAP: PM: Add pm-...
209
210
211
212
213
214
215
  
  	t = sched_clock();
  
  	for (i = 0; i < 4; i++)
  		pwrdm->state_timer[i] = 0;
  
  	pwrdm->timer = t;
68d4778c7   Tero Kristo   OMAP: PM: Added s...
216
217
218
219
220
221
222
  	if (strncmp(pwrdm->name, "dpll", 4) == 0)
  		return 0;
  
  	d = debugfs_create_dir(pwrdm->name, (struct dentry *)dir);
  
  	(void) debugfs_create_file("suspend", S_IRUGO|S_IWUSR, d,
  			(void *)pwrdm, &pwrdm_suspend_fops);
331b93f41   Peter 'p2' De Schrijver   OMAP: PM: Add pm-...
223
224
  	return 0;
  }
c40552bc8   Kevin Hilman   OMAP3: PM debug: ...
225
226
227
228
229
230
231
232
233
234
235
236
237
238
  static int option_get(void *data, u64 *val)
  {
  	u32 *option = data;
  
  	*val = *option;
  
  	return 0;
  }
  
  static int option_set(void *data, u64 val)
  {
  	u32 *option = data;
  
  	*option = val;
6cdee9125   Thara Gopinath   OMAP: PM debugfs ...
239
  	if (option == &enable_off_mode) {
6081dc348   Kevin Hilman   OMAP: PM noop: im...
240
241
242
243
  		if (val)
  			omap_pm_enable_off_mode();
  		else
  			omap_pm_disable_off_mode();
6cdee9125   Thara Gopinath   OMAP: PM debugfs ...
244
245
246
  		if (cpu_is_omap34xx())
  			omap3_pm_off_mode_enable(val);
  	}
c40552bc8   Kevin Hilman   OMAP3: PM debug: ...
247
248
249
250
251
252
  
  	return 0;
  }
  
  DEFINE_SIMPLE_ATTRIBUTE(pm_dbg_option_fops, option_get, option_set, "%llu
  ");
331b93f41   Peter 'p2' De Schrijver   OMAP: PM: Add pm-...
253
254
255
  static int __init pm_dbg_init(void)
  {
  	struct dentry *d;
2811d6b32   Tero Kristo   OMAP: PM debug: A...
256
257
  	if (pm_dbg_init_done)
  		return 0;
331b93f41   Peter 'p2' De Schrijver   OMAP: PM: Add pm-...
258
259
260
261
262
263
264
265
  	d = debugfs_create_dir("pm_debug", NULL);
  	if (IS_ERR(d))
  		return PTR_ERR(d);
  
  	(void) debugfs_create_file("count", S_IRUGO,
  		d, (void *)DEBUG_FILE_COUNTERS, &debug_fops);
  	(void) debugfs_create_file("time", S_IRUGO,
  		d, (void *)DEBUG_FILE_TIMERS, &debug_fops);
e909d62a8   Paul Walmsley   OMAP clockdomain/...
266
  	pwrdm_for_each(pwrdms_setup, (void *)d);
331b93f41   Peter 'p2' De Schrijver   OMAP: PM: Add pm-...
267

f9fbe47cc   Vasiliy Kulikov   mach-omap2: pm: w...
268
  	(void) debugfs_create_file("enable_off_mode", S_IRUGO | S_IWUSR, d,
c40552bc8   Kevin Hilman   OMAP3: PM debug: ...
269
  				   &enable_off_mode, &pm_dbg_option_fops);
331b93f41   Peter 'p2' De Schrijver   OMAP: PM: Add pm-...
270
271
272
273
  	pm_dbg_init_done = 1;
  
  	return 0;
  }
2811d6b32   Tero Kristo   OMAP: PM debug: A...
274
  arch_initcall(pm_dbg_init);
331b93f41   Peter 'p2' De Schrijver   OMAP: PM: Add pm-...
275

331b93f41   Peter 'p2' De Schrijver   OMAP: PM: Add pm-...
276
  #endif