aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap
diff options
context:
space:
mode:
authorKevin Hilman <khilman@deeprootsystems.com>2010-01-26 22:13:02 -0500
committerPaul Walmsley <paul@pwsan.com>2010-01-26 22:13:02 -0500
commit9799aca2032ad53418ff4bc0d1a6f2cb4f79b6c0 (patch)
treef8cd85a140eb5d1bf77fff3dbec78ae93f6be183 /arch/arm/plat-omap
parentf0271d65f9ac511d2e3e1fdbcd7418a5a7df0769 (diff)
OMAP: omap_device: optionally auto-adjust device activate/deactivate latencies
First, this patch adds new worst-case latency values to the omap_device_pm_latency struct. Here the worst-case measured latencies for the activate and deactivate hooks are stored. In addition, add an option to auto-adjust the latency values used for device activate/deactivate. By setting a new 'OMAP_DEVICE_LATENCY_AUTO_ADJUST' flag in the omap_device_pm_latency struct, the omap_device layer automatically adjusts the activate/deactivate latencies to the worst-case measured values. Anytime a new worst-case value is found, it is printed to the console. Here is an example log during boot using UART2 s an example. After boot, the OPP is manually changed to the 125MHz OPP: [...] Freeing init memory: 128K omap_device: serial8250.2: new worst case deactivate latency 0: 30517 omap_device: serial8250.2: new worst case activate latency 0: 30517 omap_device: serial8250.2: new worst case activate latency 0: 218139648 omap_device: serial8250.2: new worst case deactivate latency 0: 61035 omap_device: serial8250.2: new worst case activate latency 0: 278076171 omap_device: serial8250.2: new worst case activate latency 0: 298614501 omap_device: serial8250.2: new worst case activate latency 0: 327331542 / # echo 125000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed omap_device: serial8250.2: new worst case deactivate latency 0: 91552 Motivation: this can be used as a technique to automatically determine the worst case latency values. The current method of printing a warning on every violation is too noisy to actually interact the console in order to set low OPP to discover latencies. Another motivation for this patch is that the activate/deactivate latenices can vary depending on the idlemode of the device. While working on the UARTs, I noticed that when using no-idle, the activate latencies were as high as several hundred msecs as shown above. When the UARTs are in smart-idle, the max latency is well under 100 usecs. Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com> Signed-off-by: Paul Walmsley <paul@pwsan.com>
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r--arch/arm/plat-omap/include/plat/omap_device.h4
-rw-r--r--arch/arm/plat-omap/omap_device.c41
2 files changed, 37 insertions, 8 deletions
diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index dc1fac1d805c..76d49171fed9 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -131,11 +131,15 @@ int omap_device_enable_clocks(struct omap_device *od);
131 */ 131 */
132struct omap_device_pm_latency { 132struct omap_device_pm_latency {
133 u32 deactivate_lat; 133 u32 deactivate_lat;
134 u32 deactivate_lat_worst;
134 int (*deactivate_func)(struct omap_device *od); 135 int (*deactivate_func)(struct omap_device *od);
135 u32 activate_lat; 136 u32 activate_lat;
137 u32 activate_lat_worst;
136 int (*activate_func)(struct omap_device *od); 138 int (*activate_func)(struct omap_device *od);
139 u32 flags;
137}; 140};
138 141
142#define OMAP_DEVICE_LATENCY_AUTO_ADJUST BIT(1)
139 143
140/* Get omap_device pointer from platform_device pointer */ 144/* Get omap_device pointer from platform_device pointer */
141#define to_omap_device(x) container_of((x), struct omap_device, pdev) 145#define to_omap_device(x) container_of((x), struct omap_device, pdev)
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index 1e5648d3e3d8..d8c75c8f78d7 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -148,10 +148,22 @@ static int _omap_device_activate(struct omap_device *od, u8 ignore_lat)
148 "%llu nsec\n", od->pdev.name, od->pm_lat_level, 148 "%llu nsec\n", od->pdev.name, od->pm_lat_level,
149 act_lat); 149 act_lat);
150 150
151 WARN(act_lat > odpl->activate_lat, "omap_device: %s.%d: " 151 if (act_lat > odpl->activate_lat) {
152 "activate step %d took longer than expected (%llu > %d)\n", 152 odpl->activate_lat_worst = act_lat;
153 od->pdev.name, od->pdev.id, od->pm_lat_level, 153 if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
154 act_lat, odpl->activate_lat); 154 odpl->activate_lat = act_lat;
155 pr_warning("omap_device: %s.%d: new worst case "
156 "activate latency %d: %llu\n",
157 od->pdev.name, od->pdev.id,
158 od->pm_lat_level, act_lat);
159 } else
160 pr_warning("omap_device: %s.%d: activate "
161 "latency %d higher than exptected. "
162 "(%llu > %d)\n",
163 od->pdev.name, od->pdev.id,
164 od->pm_lat_level, act_lat,
165 odpl->activate_lat);
166 }
155 167
156 od->dev_wakeup_lat -= odpl->activate_lat; 168 od->dev_wakeup_lat -= odpl->activate_lat;
157 } 169 }
@@ -204,10 +216,23 @@ static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat)
204 "%llu nsec\n", od->pdev.name, od->pm_lat_level, 216 "%llu nsec\n", od->pdev.name, od->pm_lat_level,
205 deact_lat); 217 deact_lat);
206 218
207 WARN(deact_lat > odpl->deactivate_lat, "omap_device: %s.%d: " 219 if (deact_lat > odpl->deactivate_lat) {
208 "deactivate step %d took longer than expected " 220 odpl->deactivate_lat_worst = deact_lat;
209 "(%llu > %d)\n", od->pdev.name, od->pdev.id, 221 if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
210 od->pm_lat_level, deact_lat, odpl->deactivate_lat); 222 odpl->deactivate_lat = deact_lat;
223 pr_warning("omap_device: %s.%d: new worst case "
224 "deactivate latency %d: %llu\n",
225 od->pdev.name, od->pdev.id,
226 od->pm_lat_level, deact_lat);
227 } else
228 pr_warning("omap_device: %s.%d: deactivate "
229 "latency %d higher than exptected. "
230 "(%llu > %d)\n",
231 od->pdev.name, od->pdev.id,
232 od->pm_lat_level, deact_lat,
233 odpl->deactivate_lat);
234 }
235
211 236
212 od->dev_wakeup_lat += odpl->activate_lat; 237 od->dev_wakeup_lat += odpl->activate_lat;
213 238