aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/pvr/services4/system/omap/sgxfreq_activeidle.c')
-rw-r--r--drivers/gpu/pvr/services4/system/omap/sgxfreq_activeidle.c206
1 files changed, 206 insertions, 0 deletions
diff --git a/drivers/gpu/pvr/services4/system/omap/sgxfreq_activeidle.c b/drivers/gpu/pvr/services4/system/omap/sgxfreq_activeidle.c
new file mode 100644
index 000000000000..bb9b6c7883ca
--- /dev/null
+++ b/drivers/gpu/pvr/services4/system/omap/sgxfreq_activeidle.c
@@ -0,0 +1,206 @@
1/*
2 * Copyright (C) 2012 Texas Instruments, Inc
3 *
4@License Dual MIT/GPLv2
5
6The contents of this file are subject to the MIT license as set out below.
7
8Permission is hereby granted, free of charge, to any person obtaining a copy
9of this software and associated documentation files (the "Software"), to deal
10in the Software without restriction, including without limitation the rights
11to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12copies of the Software, and to permit persons to whom the Software is
13furnished to do so, subject to the following conditions:
14
15The above copyright notice and this permission notice shall be included in
16all copies or substantial portions of the Software.
17
18Alternatively, the contents of this file may be used under the terms of
19the GNU General Public License Version 2 ("GPL") in which case the provisions
20of GPL are applicable instead of those above.
21
22If you wish to allow use of your version of this file only under the terms of
23GPL, and not to allow others to use your version of this file under the terms
24of the MIT license, indicate your decision by deleting the provisions above
25and replace them with the notice and other provisions required by GPL as set
26out in the file called "GPL-COPYING" included in this distribution. If you do
27not delete the provisions above, a recipient may use your version of this file
28under the terms of either the MIT license or GPL.
29
30This License is also included in this distribution in the file called
31"MIT-COPYING".
32
33EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
34PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
35BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
36PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
37COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
38IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
39CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40*/
41
42#include <linux/sysfs.h>
43#include "sgxfreq.h"
44
45static int activeidle_start(struct sgxfreq_sgx_data *data);
46static void activeidle_stop(void);
47static void activeidle_sgx_active(void);
48static void activeidle_sgx_idle(void);
49
50static struct activeidle_data {
51 unsigned long freq_active;
52 unsigned long freq_idle;
53 struct mutex mutex;
54 bool sgx_active;
55} aid;
56
57static struct sgxfreq_governor activeidle_gov = {
58 .name = "activeidle",
59 .gov_start = activeidle_start,
60 .gov_stop = activeidle_stop,
61 .sgx_active = activeidle_sgx_active,
62 .sgx_idle = activeidle_sgx_idle,
63};
64
65/*********************** begin sysfs interface ***********************/
66
67extern struct kobject *sgxfreq_kobj;
68
69static ssize_t show_freq_active(struct device *dev,
70 struct device_attribute *attr,
71 char *buf)
72{
73 return sprintf(buf, "%lu\n", aid.freq_active);
74}
75
76static ssize_t store_freq_active(struct device *dev,
77 struct device_attribute *attr,
78 const char *buf, size_t count)
79{
80 int ret;
81 unsigned long freq;
82
83 ret = sscanf(buf, "%lu", &freq);
84 if (ret != 1)
85 return -EINVAL;
86
87 freq = sgxfreq_get_freq_ceil(freq);
88
89 mutex_lock(&aid.mutex);
90
91 aid.freq_active = freq;
92 if (aid.sgx_active)
93 sgxfreq_set_freq_request(aid.freq_active);
94
95 mutex_unlock(&aid.mutex);
96
97 return count;
98}
99
100static ssize_t show_freq_idle(struct device *dev, struct device_attribute *attr,
101 char *buf)
102{
103 return sprintf(buf, "%lu\n", aid.freq_idle);
104}
105
106static ssize_t store_freq_idle(struct device *dev, struct device_attribute *attr,
107 const char *buf, size_t count)
108{
109 int ret;
110 unsigned long freq;
111
112 ret = sscanf(buf, "%lu", &freq);
113 if (ret != 1)
114 return -EINVAL;
115
116 freq = sgxfreq_get_freq_floor(freq);
117
118 mutex_lock(&aid.mutex);
119
120 aid.freq_idle = freq;
121 if (!aid.sgx_active)
122 sgxfreq_set_freq_request(aid.freq_idle);
123
124 mutex_unlock(&aid.mutex);
125
126 return count;
127}
128static DEVICE_ATTR(freq_active, 0644, show_freq_active, store_freq_active);
129static DEVICE_ATTR(freq_idle, 0644, show_freq_idle, store_freq_idle);
130
131static struct attribute *activeidle_attributes[] = {
132 &dev_attr_freq_active.attr,
133 &dev_attr_freq_idle.attr,
134 NULL
135};
136
137static struct attribute_group activeidle_attr_group = {
138 .attrs = activeidle_attributes,
139 .name = "activeidle",
140};
141
142/************************ end sysfs interface ************************/
143
144int activeidle_init(void)
145{
146 int ret;
147
148 mutex_init(&aid.mutex);
149
150 ret = sgxfreq_register_governor(&activeidle_gov);
151 if (ret)
152 return ret;
153
154 aid.freq_idle = sgxfreq_get_freq_min();
155 aid.freq_active = sgxfreq_get_freq_max();
156
157 return 0;
158}
159
160int activeidle_deinit(void)
161{
162 return 0;
163}
164
165static int activeidle_start(struct sgxfreq_sgx_data *data)
166{
167 int ret;
168
169 aid.sgx_active = data->active;
170
171 ret = sysfs_create_group(sgxfreq_kobj, &activeidle_attr_group);
172 if (ret)
173 return ret;
174
175 if (aid.sgx_active)
176 sgxfreq_set_freq_request(aid.freq_active);
177 else
178 sgxfreq_set_freq_request(aid.freq_idle);
179
180 return 0;
181}
182
183static void activeidle_stop(void)
184{
185 sysfs_remove_group(sgxfreq_kobj, &activeidle_attr_group);
186}
187
188static void activeidle_sgx_active(void)
189{
190 mutex_lock(&aid.mutex);
191
192 aid.sgx_active = true;
193 sgxfreq_set_freq_request(aid.freq_active);
194
195 mutex_unlock(&aid.mutex);
196}
197
198static void activeidle_sgx_idle(void)
199{
200 mutex_lock(&aid.mutex);
201
202 aid.sgx_active = false;
203 sgxfreq_set_freq_request(aid.freq_idle);
204
205 mutex_unlock(&aid.mutex);
206}