aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/devfreq/tegra-devfreq.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-14 23:21:54 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-14 23:21:54 -0400
commit2481bc75283ea10e75d5fb1a8b42af363fc4b45c (patch)
tree42dd659a23041a08955aceebab859b616164c2f6 /drivers/devfreq/tegra-devfreq.c
parent8691c130fae136bb2b7d0554422a2dff4c6ac169 (diff)
parent518b4e272d99dcb13699b229ea480bc845c141f6 (diff)
Merge tag 'pm+acpi-4.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management and ACPI updates from Rafael Wysocki: "These are mostly fixes and cleanups all over, although there are a few items that sort of fall into the new feature category. First off, we have new callbacks for PM domains that should help us to handle some issues related to device initialization in a better way. There also is some consolidation in the unified device properties API area allowing us to use that inferface for accessing data coming from platform initialization code in addition to firmware-provided data. We have some new device/CPU IDs in a few drivers, support for new chips and a new cpufreq driver too. Specifics: - Generic PM domains support update including new PM domain callbacks to handle device initialization better (Russell King, Rafael J Wysocki, Kevin Hilman) - Unified device properties API update including a new mechanism for accessing data provided by platform initialization code (Rafael J Wysocki, Adrian Hunter) - ARM cpuidle update including ARM32/ARM64 handling consolidation (Daniel Lezcano) - intel_idle update including support for the Silvermont Core in the Baytrail SOC and for the Airmont Core in the Cherrytrail and Braswell SOCs (Len Brown, Mathias Krause) - New cpufreq driver for Hisilicon ACPU (Leo Yan) - intel_pstate update including support for the Knights Landing chip (Dasaratharaman Chandramouli, Kristen Carlson Accardi) - QorIQ cpufreq driver update (Tang Yuantian, Arnd Bergmann) - powernv cpufreq driver update (Shilpasri G Bhat) - devfreq update including Tegra support changes (Tomeu Vizoso, MyungJoo Ham, Chanwoo Choi) - powercap RAPL (Running-Average Power Limit) driver update including support for Intel Broadwell server chips (Jacob Pan, Mathias Krause) - ACPI device enumeration update related to the handling of the special PRP0001 device ID allowing DT-style 'compatible' property to be used for ACPI device identification (Rafael J Wysocki) - ACPI EC driver update including limited _DEP support (Lan Tianyu, Lv Zheng) - ACPI backlight driver update including a new mechanism to allow native backlight handling to be forced on non-Windows 8 systems and a new quirk for Lenovo Ideapad Z570 (Aaron Lu, Hans de Goede) - New Windows Vista compatibility quirk for Sony VGN-SR19XN (Chen Yu) - Assorted ACPI fixes and cleanups (Aaron Lu, Martin Kepplinger, Masanari Iida, Mika Westerberg, Nan Li, Rafael J Wysocki) - Fixes related to suspend-to-idle for the iTCO watchdog driver and the ACPI core system suspend/resume code (Rafael J Wysocki, Chen Yu) - PM tracing support for the suspend phase of system suspend/resume transitions (Zhonghui Fu) - Configurable delay for the system suspend/resume testing facility (Brian Norris) - PNP subsystem cleanups (Peter Huewe, Rafael J Wysocki)" * tag 'pm+acpi-4.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (74 commits) ACPI / scan: Fix NULL pointer dereference in acpi_companion_match() ACPI / scan: Rework modalias creation when "compatible" is present intel_idle: mark cpu id array as __initconst powercap / RAPL: mark rapl_ids array as __initconst powercap / RAPL: add ID for Broadwell server intel_pstate: Knights Landing support intel_pstate: remove MSR test cpufreq: fix qoriq uniprocessor build ACPI / scan: Take the PRP0001 position in the list of IDs into account ACPI / scan: Simplify acpi_match_device() ACPI / scan: Generalize of_compatible matching device property: Introduce firmware node type for platform data device property: Make it possible to use secondary firmware nodes PM / watchdog: iTCO: stop watchdog during system suspend cpufreq: hisilicon: add acpu driver ACPI / EC: Call acpi_walk_dep_device_list() after installing EC opregion handler cpufreq: powernv: Report cpu frequency throttling intel_idle: Add support for the Airmont Core in the Cherrytrail and Braswell SOCs intel_idle: Update support for Silvermont Core in Baytrail SOC PM / devfreq: tegra: Register governor on module init ...
Diffstat (limited to 'drivers/devfreq/tegra-devfreq.c')
-rw-r--r--drivers/devfreq/tegra-devfreq.c509
1 files changed, 288 insertions, 221 deletions
diff --git a/drivers/devfreq/tegra-devfreq.c b/drivers/devfreq/tegra-devfreq.c
index 34790961af5a..13a1a6e8108c 100644
--- a/drivers/devfreq/tegra-devfreq.c
+++ b/drivers/devfreq/tegra-devfreq.c
@@ -62,7 +62,8 @@
62#define ACTMON_BELOW_WMARK_WINDOW 3 62#define ACTMON_BELOW_WMARK_WINDOW 3
63#define ACTMON_BOOST_FREQ_STEP 16000 63#define ACTMON_BOOST_FREQ_STEP 16000
64 64
65/* activity counter is incremented every 256 memory transactions, and each 65/*
66 * Activity counter is incremented every 256 memory transactions, and each
66 * transaction takes 4 EMC clocks for Tegra124; So the COUNT_WEIGHT is 67 * transaction takes 4 EMC clocks for Tegra124; So the COUNT_WEIGHT is
67 * 4 * 256 = 1024. 68 * 4 * 256 = 1024.
68 */ 69 */
@@ -85,16 +86,25 @@
85 * struct tegra_devfreq_device_config - configuration specific to an ACTMON 86 * struct tegra_devfreq_device_config - configuration specific to an ACTMON
86 * device 87 * device
87 * 88 *
88 * Coefficients and thresholds are in % 89 * Coefficients and thresholds are percentages unless otherwise noted
89 */ 90 */
90struct tegra_devfreq_device_config { 91struct tegra_devfreq_device_config {
91 u32 offset; 92 u32 offset;
92 u32 irq_mask; 93 u32 irq_mask;
93 94
95 /* Factors applied to boost_freq every consecutive watermark breach */
94 unsigned int boost_up_coeff; 96 unsigned int boost_up_coeff;
95 unsigned int boost_down_coeff; 97 unsigned int boost_down_coeff;
98
99 /* Define the watermark bounds when applied to the current avg */
96 unsigned int boost_up_threshold; 100 unsigned int boost_up_threshold;
97 unsigned int boost_down_threshold; 101 unsigned int boost_down_threshold;
102
103 /*
104 * Threshold of activity (cycles) below which the CPU frequency isn't
105 * to be taken into account. This is to avoid increasing the EMC
106 * frequency when the CPU is very busy but not accessing the bus often.
107 */
98 u32 avg_dependency_threshold; 108 u32 avg_dependency_threshold;
99}; 109};
100 110
@@ -105,7 +115,7 @@ enum tegra_actmon_device {
105 115
106static struct tegra_devfreq_device_config actmon_device_configs[] = { 116static struct tegra_devfreq_device_config actmon_device_configs[] = {
107 { 117 {
108 /* MCALL */ 118 /* MCALL: All memory accesses (including from the CPUs) */
109 .offset = 0x1c0, 119 .offset = 0x1c0,
110 .irq_mask = 1 << 26, 120 .irq_mask = 1 << 26,
111 .boost_up_coeff = 200, 121 .boost_up_coeff = 200,
@@ -114,7 +124,7 @@ static struct tegra_devfreq_device_config actmon_device_configs[] = {
114 .boost_down_threshold = 40, 124 .boost_down_threshold = 40,
115 }, 125 },
116 { 126 {
117 /* MCCPU */ 127 /* MCCPU: memory accesses from the CPUs */
118 .offset = 0x200, 128 .offset = 0x200,
119 .irq_mask = 1 << 25, 129 .irq_mask = 1 << 25,
120 .boost_up_coeff = 800, 130 .boost_up_coeff = 800,
@@ -132,25 +142,29 @@ static struct tegra_devfreq_device_config actmon_device_configs[] = {
132 */ 142 */
133struct tegra_devfreq_device { 143struct tegra_devfreq_device {
134 const struct tegra_devfreq_device_config *config; 144 const struct tegra_devfreq_device_config *config;
145 void __iomem *regs;
146 spinlock_t lock;
147
148 /* Average event count sampled in the last interrupt */
149 u32 avg_count;
135 150
136 void __iomem *regs; 151 /*
137 u32 avg_band_freq; 152 * Extra frequency to increase the target by due to consecutive
138 u32 avg_count; 153 * watermark breaches.
154 */
155 unsigned long boost_freq;
139 156
140 unsigned long target_freq; 157 /* Optimal frequency calculated from the stats for this device */
141 unsigned long boost_freq; 158 unsigned long target_freq;
142}; 159};
143 160
144struct tegra_devfreq { 161struct tegra_devfreq {
145 struct devfreq *devfreq; 162 struct devfreq *devfreq;
146 163
147 struct platform_device *pdev;
148 struct reset_control *reset; 164 struct reset_control *reset;
149 struct clk *clock; 165 struct clk *clock;
150 void __iomem *regs; 166 void __iomem *regs;
151 167
152 spinlock_t lock;
153
154 struct clk *emc_clock; 168 struct clk *emc_clock;
155 unsigned long max_freq; 169 unsigned long max_freq;
156 unsigned long cur_freq; 170 unsigned long cur_freq;
@@ -174,19 +188,43 @@ static struct tegra_actmon_emc_ratio actmon_emc_ratios[] = {
174 { 250000, 100000 }, 188 { 250000, 100000 },
175}; 189};
176 190
191static u32 actmon_readl(struct tegra_devfreq *tegra, u32 offset)
192{
193 return readl(tegra->regs + offset);
194}
195
196static void actmon_writel(struct tegra_devfreq *tegra, u32 val, u32 offset)
197{
198 writel(val, tegra->regs + offset);
199}
200
201static u32 device_readl(struct tegra_devfreq_device *dev, u32 offset)
202{
203 return readl(dev->regs + offset);
204}
205
206static void device_writel(struct tegra_devfreq_device *dev, u32 val,
207 u32 offset)
208{
209 writel(val, dev->regs + offset);
210}
211
177static unsigned long do_percent(unsigned long val, unsigned int pct) 212static unsigned long do_percent(unsigned long val, unsigned int pct)
178{ 213{
179 return val * pct / 100; 214 return val * pct / 100;
180} 215}
181 216
182static void tegra_devfreq_update_avg_wmark(struct tegra_devfreq_device *dev) 217static void tegra_devfreq_update_avg_wmark(struct tegra_devfreq *tegra,
218 struct tegra_devfreq_device *dev)
183{ 219{
184 u32 avg = dev->avg_count; 220 u32 avg = dev->avg_count;
185 u32 band = dev->avg_band_freq * ACTMON_SAMPLING_PERIOD; 221 u32 avg_band_freq = tegra->max_freq * ACTMON_DEFAULT_AVG_BAND / KHZ;
222 u32 band = avg_band_freq * ACTMON_SAMPLING_PERIOD;
223
224 device_writel(dev, avg + band, ACTMON_DEV_AVG_UPPER_WMARK);
186 225
187 writel(avg + band, dev->regs + ACTMON_DEV_AVG_UPPER_WMARK); 226 avg = max(dev->avg_count, band);
188 avg = max(avg, band); 227 device_writel(dev, avg - band, ACTMON_DEV_AVG_LOWER_WMARK);
189 writel(avg - band, dev->regs + ACTMON_DEV_AVG_LOWER_WMARK);
190} 228}
191 229
192static void tegra_devfreq_update_wmark(struct tegra_devfreq *tegra, 230static void tegra_devfreq_update_wmark(struct tegra_devfreq *tegra,
@@ -194,96 +232,96 @@ static void tegra_devfreq_update_wmark(struct tegra_devfreq *tegra,
194{ 232{
195 u32 val = tegra->cur_freq * ACTMON_SAMPLING_PERIOD; 233 u32 val = tegra->cur_freq * ACTMON_SAMPLING_PERIOD;
196 234
197 writel(do_percent(val, dev->config->boost_up_threshold), 235 device_writel(dev, do_percent(val, dev->config->boost_up_threshold),
198 dev->regs + ACTMON_DEV_UPPER_WMARK); 236 ACTMON_DEV_UPPER_WMARK);
199 237
200 writel(do_percent(val, dev->config->boost_down_threshold), 238 device_writel(dev, do_percent(val, dev->config->boost_down_threshold),
201 dev->regs + ACTMON_DEV_LOWER_WMARK); 239 ACTMON_DEV_LOWER_WMARK);
202} 240}
203 241
204static void actmon_write_barrier(struct tegra_devfreq *tegra) 242static void actmon_write_barrier(struct tegra_devfreq *tegra)
205{ 243{
206 /* ensure the update has reached the ACTMON */ 244 /* ensure the update has reached the ACTMON */
207 wmb(); 245 wmb();
208 readl(tegra->regs + ACTMON_GLB_STATUS); 246 actmon_readl(tegra, ACTMON_GLB_STATUS);
209} 247}
210 248
211static irqreturn_t actmon_isr(int irq, void *data) 249static void actmon_isr_device(struct tegra_devfreq *tegra,
250 struct tegra_devfreq_device *dev)
212{ 251{
213 struct tegra_devfreq *tegra = data;
214 struct tegra_devfreq_device *dev = NULL;
215 unsigned long flags; 252 unsigned long flags;
216 u32 val; 253 u32 intr_status, dev_ctrl;
217 unsigned int i;
218
219 val = readl(tegra->regs + ACTMON_GLB_STATUS);
220
221 for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) {
222 if (val & tegra->devices[i].config->irq_mask) {
223 dev = tegra->devices + i;
224 break;
225 }
226 }
227
228 if (!dev)
229 return IRQ_NONE;
230 254
231 spin_lock_irqsave(&tegra->lock, flags); 255 spin_lock_irqsave(&dev->lock, flags);
232 256
233 dev->avg_count = readl(dev->regs + ACTMON_DEV_AVG_COUNT); 257 dev->avg_count = device_readl(dev, ACTMON_DEV_AVG_COUNT);
234 tegra_devfreq_update_avg_wmark(dev); 258 tegra_devfreq_update_avg_wmark(tegra, dev);
235 259
236 val = readl(dev->regs + ACTMON_DEV_INTR_STATUS); 260 intr_status = device_readl(dev, ACTMON_DEV_INTR_STATUS);
237 if (val & ACTMON_DEV_INTR_CONSECUTIVE_UPPER) { 261 dev_ctrl = device_readl(dev, ACTMON_DEV_CTRL);
238 val = readl(dev->regs + ACTMON_DEV_CTRL) |
239 ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN |
240 ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN;
241 262
263 if (intr_status & ACTMON_DEV_INTR_CONSECUTIVE_UPPER) {
242 /* 264 /*
243 * new_boost = min(old_boost * up_coef + step, max_freq) 265 * new_boost = min(old_boost * up_coef + step, max_freq)
244 */ 266 */
245 dev->boost_freq = do_percent(dev->boost_freq, 267 dev->boost_freq = do_percent(dev->boost_freq,
246 dev->config->boost_up_coeff); 268 dev->config->boost_up_coeff);
247 dev->boost_freq += ACTMON_BOOST_FREQ_STEP; 269 dev->boost_freq += ACTMON_BOOST_FREQ_STEP;
248 if (dev->boost_freq >= tegra->max_freq) {
249 dev->boost_freq = tegra->max_freq;
250 val &= ~ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN;
251 }
252 writel(val, dev->regs + ACTMON_DEV_CTRL);
253 } else if (val & ACTMON_DEV_INTR_CONSECUTIVE_LOWER) {
254 val = readl(dev->regs + ACTMON_DEV_CTRL) |
255 ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN |
256 ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN;
257 270
271 dev_ctrl |= ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN;
272
273 if (dev->boost_freq >= tegra->max_freq)
274 dev->boost_freq = tegra->max_freq;
275 else
276 dev_ctrl |= ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN;
277 } else if (intr_status & ACTMON_DEV_INTR_CONSECUTIVE_LOWER) {
258 /* 278 /*
259 * new_boost = old_boost * down_coef 279 * new_boost = old_boost * down_coef
260 * or 0 if (old_boost * down_coef < step / 2) 280 * or 0 if (old_boost * down_coef < step / 2)
261 */ 281 */
262 dev->boost_freq = do_percent(dev->boost_freq, 282 dev->boost_freq = do_percent(dev->boost_freq,
263 dev->config->boost_down_coeff); 283 dev->config->boost_down_coeff);
264 if (dev->boost_freq < (ACTMON_BOOST_FREQ_STEP >> 1)) { 284
285 dev_ctrl |= ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN;
286
287 if (dev->boost_freq < (ACTMON_BOOST_FREQ_STEP >> 1))
265 dev->boost_freq = 0; 288 dev->boost_freq = 0;
266 val &= ~ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN; 289 else
267 } 290 dev_ctrl |= ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN;
268 writel(val, dev->regs + ACTMON_DEV_CTRL);
269 } 291 }
270 292
271 if (dev->config->avg_dependency_threshold) { 293 if (dev->config->avg_dependency_threshold) {
272 val = readl(dev->regs + ACTMON_DEV_CTRL);
273 if (dev->avg_count >= dev->config->avg_dependency_threshold) 294 if (dev->avg_count >= dev->config->avg_dependency_threshold)
274 val |= ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN; 295 dev_ctrl |= ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN;
275 else if (dev->boost_freq == 0) 296 else if (dev->boost_freq == 0)
276 val &= ~ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN; 297 dev_ctrl &= ~ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN;
277 writel(val, dev->regs + ACTMON_DEV_CTRL);
278 } 298 }
279 299
280 writel(ACTMON_INTR_STATUS_CLEAR, dev->regs + ACTMON_DEV_INTR_STATUS); 300 device_writel(dev, dev_ctrl, ACTMON_DEV_CTRL);
301
302 device_writel(dev, ACTMON_INTR_STATUS_CLEAR, ACTMON_DEV_INTR_STATUS);
281 303
282 actmon_write_barrier(tegra); 304 actmon_write_barrier(tegra);
283 305
284 spin_unlock_irqrestore(&tegra->lock, flags); 306 spin_unlock_irqrestore(&dev->lock, flags);
307}
285 308
286 return IRQ_WAKE_THREAD; 309static irqreturn_t actmon_isr(int irq, void *data)
310{
311 struct tegra_devfreq *tegra = data;
312 bool handled = false;
313 unsigned int i;
314 u32 val;
315
316 val = actmon_readl(tegra, ACTMON_GLB_STATUS);
317 for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) {
318 if (val & tegra->devices[i].config->irq_mask) {
319 actmon_isr_device(tegra, tegra->devices + i);
320 handled = true;
321 }
322 }
323
324 return handled ? IRQ_WAKE_THREAD : IRQ_NONE;
287} 325}
288 326
289static unsigned long actmon_cpu_to_emc_rate(struct tegra_devfreq *tegra, 327static unsigned long actmon_cpu_to_emc_rate(struct tegra_devfreq *tegra,
@@ -317,7 +355,7 @@ static void actmon_update_target(struct tegra_devfreq *tegra,
317 static_cpu_emc_freq = actmon_cpu_to_emc_rate(tegra, cpu_freq); 355 static_cpu_emc_freq = actmon_cpu_to_emc_rate(tegra, cpu_freq);
318 } 356 }
319 357
320 spin_lock_irqsave(&tegra->lock, flags); 358 spin_lock_irqsave(&dev->lock, flags);
321 359
322 dev->target_freq = dev->avg_count / ACTMON_SAMPLING_PERIOD; 360 dev->target_freq = dev->avg_count / ACTMON_SAMPLING_PERIOD;
323 avg_sustain_coef = 100 * 100 / dev->config->boost_up_threshold; 361 avg_sustain_coef = 100 * 100 / dev->config->boost_up_threshold;
@@ -327,7 +365,7 @@ static void actmon_update_target(struct tegra_devfreq *tegra,
327 if (dev->avg_count >= dev->config->avg_dependency_threshold) 365 if (dev->avg_count >= dev->config->avg_dependency_threshold)
328 dev->target_freq = max(dev->target_freq, static_cpu_emc_freq); 366 dev->target_freq = max(dev->target_freq, static_cpu_emc_freq);
329 367
330 spin_unlock_irqrestore(&tegra->lock, flags); 368 spin_unlock_irqrestore(&dev->lock, flags);
331} 369}
332 370
333static irqreturn_t actmon_thread_isr(int irq, void *data) 371static irqreturn_t actmon_thread_isr(int irq, void *data)
@@ -345,131 +383,110 @@ static int tegra_actmon_rate_notify_cb(struct notifier_block *nb,
345 unsigned long action, void *ptr) 383 unsigned long action, void *ptr)
346{ 384{
347 struct clk_notifier_data *data = ptr; 385 struct clk_notifier_data *data = ptr;
348 struct tegra_devfreq *tegra = container_of(nb, struct tegra_devfreq, 386 struct tegra_devfreq *tegra;
349 rate_change_nb); 387 struct tegra_devfreq_device *dev;
350 unsigned int i; 388 unsigned int i;
351 unsigned long flags; 389 unsigned long flags;
352 390
353 spin_lock_irqsave(&tegra->lock, flags); 391 if (action != POST_RATE_CHANGE)
392 return NOTIFY_OK;
354 393
355 switch (action) { 394 tegra = container_of(nb, struct tegra_devfreq, rate_change_nb);
356 case POST_RATE_CHANGE:
357 tegra->cur_freq = data->new_rate / KHZ;
358 395
359 for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) 396 tegra->cur_freq = data->new_rate / KHZ;
360 tegra_devfreq_update_wmark(tegra, tegra->devices + i);
361 397
362 actmon_write_barrier(tegra); 398 for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) {
363 break; 399 dev = &tegra->devices[i];
364 case PRE_RATE_CHANGE:
365 /* fall through */
366 case ABORT_RATE_CHANGE:
367 break;
368 };
369 400
370 spin_unlock_irqrestore(&tegra->lock, flags); 401 spin_lock_irqsave(&dev->lock, flags);
402 tegra_devfreq_update_wmark(tegra, dev);
403 spin_unlock_irqrestore(&dev->lock, flags);
404 }
405
406 actmon_write_barrier(tegra);
371 407
372 return NOTIFY_OK; 408 return NOTIFY_OK;
373} 409}
374 410
375static void tegra_actmon_configure_device(struct tegra_devfreq *tegra, 411static void tegra_actmon_enable_interrupts(struct tegra_devfreq *tegra)
376 struct tegra_devfreq_device *dev)
377{ 412{
413 struct tegra_devfreq_device *dev;
378 u32 val; 414 u32 val;
415 unsigned int i;
379 416
380 dev->avg_band_freq = tegra->max_freq * ACTMON_DEFAULT_AVG_BAND / KHZ; 417 for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) {
381 dev->target_freq = tegra->cur_freq; 418 dev = &tegra->devices[i];
382
383 dev->avg_count = tegra->cur_freq * ACTMON_SAMPLING_PERIOD;
384 writel(dev->avg_count, dev->regs + ACTMON_DEV_INIT_AVG);
385
386 tegra_devfreq_update_avg_wmark(dev);
387 tegra_devfreq_update_wmark(tegra, dev);
388
389 writel(ACTMON_COUNT_WEIGHT, dev->regs + ACTMON_DEV_COUNT_WEIGHT);
390 writel(ACTMON_INTR_STATUS_CLEAR, dev->regs + ACTMON_DEV_INTR_STATUS);
391
392 val = 0;
393 val |= ACTMON_DEV_CTRL_ENB_PERIODIC |
394 ACTMON_DEV_CTRL_AVG_ABOVE_WMARK_EN |
395 ACTMON_DEV_CTRL_AVG_BELOW_WMARK_EN;
396 val |= (ACTMON_AVERAGE_WINDOW_LOG2 - 1)
397 << ACTMON_DEV_CTRL_K_VAL_SHIFT;
398 val |= (ACTMON_BELOW_WMARK_WINDOW - 1)
399 << ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_NUM_SHIFT;
400 val |= (ACTMON_ABOVE_WMARK_WINDOW - 1)
401 << ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_NUM_SHIFT;
402 val |= ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN |
403 ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN;
404
405 writel(val, dev->regs + ACTMON_DEV_CTRL);
406 419
407 actmon_write_barrier(tegra); 420 val = device_readl(dev, ACTMON_DEV_CTRL);
421 val |= ACTMON_DEV_CTRL_AVG_ABOVE_WMARK_EN;
422 val |= ACTMON_DEV_CTRL_AVG_BELOW_WMARK_EN;
423 val |= ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN;
424 val |= ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN;
408 425
409 val = readl(dev->regs + ACTMON_DEV_CTRL); 426 device_writel(dev, val, ACTMON_DEV_CTRL);
410 val |= ACTMON_DEV_CTRL_ENB; 427 }
411 writel(val, dev->regs + ACTMON_DEV_CTRL);
412 428
413 actmon_write_barrier(tegra); 429 actmon_write_barrier(tegra);
414} 430}
415 431
416static int tegra_devfreq_suspend(struct device *dev) 432static void tegra_actmon_disable_interrupts(struct tegra_devfreq *tegra)
417{ 433{
418 struct platform_device *pdev; 434 struct tegra_devfreq_device *dev;
419 struct tegra_devfreq *tegra;
420 struct tegra_devfreq_device *actmon_dev;
421 unsigned int i;
422 u32 val; 435 u32 val;
423 436 unsigned int i;
424 pdev = container_of(dev, struct platform_device, dev);
425 tegra = platform_get_drvdata(pdev);
426 437
427 for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) { 438 for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) {
428 actmon_dev = &tegra->devices[i]; 439 dev = &tegra->devices[i];
429
430 val = readl(actmon_dev->regs + ACTMON_DEV_CTRL);
431 val &= ~ACTMON_DEV_CTRL_ENB;
432 writel(val, actmon_dev->regs + ACTMON_DEV_CTRL);
433 440
434 writel(ACTMON_INTR_STATUS_CLEAR, 441 val = device_readl(dev, ACTMON_DEV_CTRL);
435 actmon_dev->regs + ACTMON_DEV_INTR_STATUS); 442 val &= ~ACTMON_DEV_CTRL_AVG_ABOVE_WMARK_EN;
443 val &= ~ACTMON_DEV_CTRL_AVG_BELOW_WMARK_EN;
444 val &= ~ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_EN;
445 val &= ~ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_EN;
436 446
437 actmon_write_barrier(tegra); 447 device_writel(dev, val, ACTMON_DEV_CTRL);
438 } 448 }
439 449
440 return 0; 450 actmon_write_barrier(tegra);
441} 451}
442 452
443static int tegra_devfreq_resume(struct device *dev) 453static void tegra_actmon_configure_device(struct tegra_devfreq *tegra,
454 struct tegra_devfreq_device *dev)
444{ 455{
445 struct platform_device *pdev; 456 u32 val = 0;
446 struct tegra_devfreq *tegra;
447 struct tegra_devfreq_device *actmon_dev;
448 unsigned int i;
449 457
450 pdev = container_of(dev, struct platform_device, dev); 458 dev->target_freq = tegra->cur_freq;
451 tegra = platform_get_drvdata(pdev);
452 459
453 for (i = 0; i < ARRAY_SIZE(tegra->devices); i++) { 460 dev->avg_count = tegra->cur_freq * ACTMON_SAMPLING_PERIOD;
454 actmon_dev = &tegra->devices[i]; 461 device_writel(dev, dev->avg_count, ACTMON_DEV_INIT_AVG);
455 462
456 tegra_actmon_configure_device(tegra, actmon_dev); 463 tegra_devfreq_update_avg_wmark(tegra, dev);
457 } 464 tegra_devfreq_update_wmark(tegra, dev);
458 465
459 return 0; 466 device_writel(dev, ACTMON_COUNT_WEIGHT, ACTMON_DEV_COUNT_WEIGHT);
467 device_writel(dev, ACTMON_INTR_STATUS_CLEAR, ACTMON_DEV_INTR_STATUS);
468
469 val |= ACTMON_DEV_CTRL_ENB_PERIODIC;
470 val |= (ACTMON_AVERAGE_WINDOW_LOG2 - 1)
471 << ACTMON_DEV_CTRL_K_VAL_SHIFT;
472 val |= (ACTMON_BELOW_WMARK_WINDOW - 1)
473 << ACTMON_DEV_CTRL_CONSECUTIVE_BELOW_WMARK_NUM_SHIFT;
474 val |= (ACTMON_ABOVE_WMARK_WINDOW - 1)
475 << ACTMON_DEV_CTRL_CONSECUTIVE_ABOVE_WMARK_NUM_SHIFT;
476 val |= ACTMON_DEV_CTRL_ENB;
477
478 device_writel(dev, val, ACTMON_DEV_CTRL);
479
480 actmon_write_barrier(tegra);
460} 481}
461 482
462static int tegra_devfreq_target(struct device *dev, unsigned long *freq, 483static int tegra_devfreq_target(struct device *dev, unsigned long *freq,
463 u32 flags) 484 u32 flags)
464{ 485{
465 struct platform_device *pdev; 486 struct tegra_devfreq *tegra = dev_get_drvdata(dev);
466 struct tegra_devfreq *tegra;
467 struct dev_pm_opp *opp; 487 struct dev_pm_opp *opp;
468 unsigned long rate = *freq * KHZ; 488 unsigned long rate = *freq * KHZ;
469 489
470 pdev = container_of(dev, struct platform_device, dev);
471 tegra = platform_get_drvdata(pdev);
472
473 rcu_read_lock(); 490 rcu_read_lock();
474 opp = devfreq_recommended_opp(dev, &rate, flags); 491 opp = devfreq_recommended_opp(dev, &rate, flags);
475 if (IS_ERR(opp)) { 492 if (IS_ERR(opp)) {
@@ -480,10 +497,8 @@ static int tegra_devfreq_target(struct device *dev, unsigned long *freq,
480 rate = dev_pm_opp_get_freq(opp); 497 rate = dev_pm_opp_get_freq(opp);
481 rcu_read_unlock(); 498 rcu_read_unlock();
482 499
483 /* TODO: Once we have per-user clk constraints, set a floor */ 500 clk_set_min_rate(tegra->emc_clock, rate);
484 clk_set_rate(tegra->emc_clock, rate); 501 clk_set_rate(tegra->emc_clock, 0);
485
486 /* TODO: Set voltage as well */
487 502
488 return 0; 503 return 0;
489} 504}
@@ -491,13 +506,9 @@ static int tegra_devfreq_target(struct device *dev, unsigned long *freq,
491static int tegra_devfreq_get_dev_status(struct device *dev, 506static int tegra_devfreq_get_dev_status(struct device *dev,
492 struct devfreq_dev_status *stat) 507 struct devfreq_dev_status *stat)
493{ 508{
494 struct platform_device *pdev; 509 struct tegra_devfreq *tegra = dev_get_drvdata(dev);
495 struct tegra_devfreq *tegra;
496 struct tegra_devfreq_device *actmon_dev; 510 struct tegra_devfreq_device *actmon_dev;
497 511
498 pdev = container_of(dev, struct platform_device, dev);
499 tegra = platform_get_drvdata(pdev);
500
501 stat->current_frequency = tegra->cur_freq; 512 stat->current_frequency = tegra->cur_freq;
502 513
503 /* To be used by the tegra governor */ 514 /* To be used by the tegra governor */
@@ -508,7 +519,7 @@ static int tegra_devfreq_get_dev_status(struct device *dev,
508 actmon_dev = &tegra->devices[MCALL]; 519 actmon_dev = &tegra->devices[MCALL];
509 520
510 /* Number of cycles spent on memory access */ 521 /* Number of cycles spent on memory access */
511 stat->busy_time = actmon_dev->avg_count; 522 stat->busy_time = device_readl(actmon_dev, ACTMON_DEV_AVG_COUNT);
512 523
513 /* The bus can be considered to be saturated way before 100% */ 524 /* The bus can be considered to be saturated way before 100% */
514 stat->busy_time *= 100 / BUS_SATURATION_RATIO; 525 stat->busy_time *= 100 / BUS_SATURATION_RATIO;
@@ -516,11 +527,19 @@ static int tegra_devfreq_get_dev_status(struct device *dev,
516 /* Number of cycles in a sampling period */ 527 /* Number of cycles in a sampling period */
517 stat->total_time = ACTMON_SAMPLING_PERIOD * tegra->cur_freq; 528 stat->total_time = ACTMON_SAMPLING_PERIOD * tegra->cur_freq;
518 529
530 stat->busy_time = min(stat->busy_time, stat->total_time);
531
519 return 0; 532 return 0;
520} 533}
521 534
522static int tegra_devfreq_get_target(struct devfreq *devfreq, 535static struct devfreq_dev_profile tegra_devfreq_profile = {
523 unsigned long *freq) 536 .polling_ms = 0,
537 .target = tegra_devfreq_target,
538 .get_dev_status = tegra_devfreq_get_dev_status,
539};
540
541static int tegra_governor_get_target(struct devfreq *devfreq,
542 unsigned long *freq)
524{ 543{
525 struct devfreq_dev_status stat; 544 struct devfreq_dev_status stat;
526 struct tegra_devfreq *tegra; 545 struct tegra_devfreq *tegra;
@@ -548,22 +567,43 @@ static int tegra_devfreq_get_target(struct devfreq *devfreq,
548 return 0; 567 return 0;
549} 568}
550 569
551static int tegra_devfreq_event_handler(struct devfreq *devfreq, 570static int tegra_governor_event_handler(struct devfreq *devfreq,
552 unsigned int event, void *data) 571 unsigned int event, void *data)
553{ 572{
554 return 0; 573 struct tegra_devfreq *tegra;
574 int ret = 0;
575
576 tegra = dev_get_drvdata(devfreq->dev.parent);
577
578 switch (event) {
579 case DEVFREQ_GOV_START:
580 devfreq_monitor_start(devfreq);
581 tegra_actmon_enable_interrupts(tegra);
582 break;
583
584 case DEVFREQ_GOV_STOP:
585 tegra_actmon_disable_interrupts(tegra);
586 devfreq_monitor_stop(devfreq);
587 break;
588
589 case DEVFREQ_GOV_SUSPEND:
590 tegra_actmon_disable_interrupts(tegra);
591 devfreq_monitor_suspend(devfreq);
592 break;
593
594 case DEVFREQ_GOV_RESUME:
595 devfreq_monitor_resume(devfreq);
596 tegra_actmon_enable_interrupts(tegra);
597 break;
598 }
599
600 return ret;
555} 601}
556 602
557static struct devfreq_governor tegra_devfreq_governor = { 603static struct devfreq_governor tegra_devfreq_governor = {
558 .name = "tegra", 604 .name = "tegra_actmon",
559 .get_target_freq = tegra_devfreq_get_target, 605 .get_target_freq = tegra_governor_get_target,
560 .event_handler = tegra_devfreq_event_handler, 606 .event_handler = tegra_governor_event_handler,
561};
562
563static struct devfreq_dev_profile tegra_devfreq_profile = {
564 .polling_ms = 0,
565 .target = tegra_devfreq_target,
566 .get_dev_status = tegra_devfreq_get_dev_status,
567}; 607};
568 608
569static int tegra_devfreq_probe(struct platform_device *pdev) 609static int tegra_devfreq_probe(struct platform_device *pdev)
@@ -571,8 +611,8 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
571 struct tegra_devfreq *tegra; 611 struct tegra_devfreq *tegra;
572 struct tegra_devfreq_device *dev; 612 struct tegra_devfreq_device *dev;
573 struct resource *res; 613 struct resource *res;
574 unsigned long max_freq;
575 unsigned int i; 614 unsigned int i;
615 unsigned long rate;
576 int irq; 616 int irq;
577 int err; 617 int err;
578 618
@@ -580,19 +620,11 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
580 if (!tegra) 620 if (!tegra)
581 return -ENOMEM; 621 return -ENOMEM;
582 622
583 spin_lock_init(&tegra->lock);
584
585 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 623 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
586 if (!res) {
587 dev_err(&pdev->dev, "Failed to get regs resource\n");
588 return -ENODEV;
589 }
590 624
591 tegra->regs = devm_ioremap_resource(&pdev->dev, res); 625 tegra->regs = devm_ioremap_resource(&pdev->dev, res);
592 if (IS_ERR(tegra->regs)) { 626 if (IS_ERR(tegra->regs))
593 dev_err(&pdev->dev, "Failed to get IO memory\n");
594 return PTR_ERR(tegra->regs); 627 return PTR_ERR(tegra->regs);
595 }
596 628
597 tegra->reset = devm_reset_control_get(&pdev->dev, "actmon"); 629 tegra->reset = devm_reset_control_get(&pdev->dev, "actmon");
598 if (IS_ERR(tegra->reset)) { 630 if (IS_ERR(tegra->reset)) {
@@ -612,11 +644,7 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
612 return PTR_ERR(tegra->emc_clock); 644 return PTR_ERR(tegra->emc_clock);
613 } 645 }
614 646
615 err = of_init_opp_table(&pdev->dev); 647 clk_set_rate(tegra->emc_clock, ULONG_MAX);
616 if (err) {
617 dev_err(&pdev->dev, "Failed to init operating point table\n");
618 return err;
619 }
620 648
621 tegra->rate_change_nb.notifier_call = tegra_actmon_rate_notify_cb; 649 tegra->rate_change_nb.notifier_call = tegra_actmon_rate_notify_cb;
622 err = clk_notifier_register(tegra->emc_clock, &tegra->rate_change_nb); 650 err = clk_notifier_register(tegra->emc_clock, &tegra->rate_change_nb);
@@ -630,43 +658,41 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
630 658
631 err = clk_prepare_enable(tegra->clock); 659 err = clk_prepare_enable(tegra->clock);
632 if (err) { 660 if (err) {
633 reset_control_deassert(tegra->reset); 661 dev_err(&pdev->dev,
662 "Failed to prepare and enable ACTMON clock\n");
634 return err; 663 return err;
635 } 664 }
636 665
637 reset_control_deassert(tegra->reset); 666 reset_control_deassert(tegra->reset);
638 667
639 max_freq = clk_round_rate(tegra->emc_clock, ULONG_MAX); 668 tegra->max_freq = clk_round_rate(tegra->emc_clock, ULONG_MAX) / KHZ;
640 tegra->max_freq = max_freq / KHZ;
641
642 clk_set_rate(tegra->emc_clock, max_freq);
643
644 tegra->cur_freq = clk_get_rate(tegra->emc_clock) / KHZ; 669 tegra->cur_freq = clk_get_rate(tegra->emc_clock) / KHZ;
645 670
646 writel(ACTMON_SAMPLING_PERIOD - 1, 671 actmon_writel(tegra, ACTMON_SAMPLING_PERIOD - 1,
647 tegra->regs + ACTMON_GLB_PERIOD_CTRL); 672 ACTMON_GLB_PERIOD_CTRL);
648 673
649 for (i = 0; i < ARRAY_SIZE(actmon_device_configs); i++) { 674 for (i = 0; i < ARRAY_SIZE(actmon_device_configs); i++) {
650 dev = tegra->devices + i; 675 dev = tegra->devices + i;
651 dev->config = actmon_device_configs + i; 676 dev->config = actmon_device_configs + i;
652 dev->regs = tegra->regs + dev->config->offset; 677 dev->regs = tegra->regs + dev->config->offset;
678 spin_lock_init(&dev->lock);
653 679
654 tegra_actmon_configure_device(tegra, tegra->devices + i); 680 tegra_actmon_configure_device(tegra, dev);
655 } 681 }
656 682
657 err = devfreq_add_governor(&tegra_devfreq_governor); 683 for (rate = 0; rate <= tegra->max_freq * KHZ; rate++) {
658 if (err) { 684 rate = clk_round_rate(tegra->emc_clock, rate);
659 dev_err(&pdev->dev, "Failed to add governor\n"); 685 dev_pm_opp_add(&pdev->dev, rate, 0);
660 return err;
661 } 686 }
662 687
663 tegra_devfreq_profile.initial_freq = clk_get_rate(tegra->emc_clock);
664 tegra->devfreq = devm_devfreq_add_device(&pdev->dev,
665 &tegra_devfreq_profile,
666 "tegra",
667 NULL);
668
669 irq = platform_get_irq(pdev, 0); 688 irq = platform_get_irq(pdev, 0);
689 if (irq <= 0) {
690 dev_err(&pdev->dev, "Failed to get IRQ\n");
691 return -ENODEV;
692 }
693
694 platform_set_drvdata(pdev, tegra);
695
670 err = devm_request_threaded_irq(&pdev->dev, irq, actmon_isr, 696 err = devm_request_threaded_irq(&pdev->dev, irq, actmon_isr,
671 actmon_thread_isr, IRQF_SHARED, 697 actmon_thread_isr, IRQF_SHARED,
672 "tegra-devfreq", tegra); 698 "tegra-devfreq", tegra);
@@ -675,7 +701,11 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
675 return err; 701 return err;
676 } 702 }
677 703
678 platform_set_drvdata(pdev, tegra); 704 tegra_devfreq_profile.initial_freq = clk_get_rate(tegra->emc_clock);
705 tegra->devfreq = devm_devfreq_add_device(&pdev->dev,
706 &tegra_devfreq_profile,
707 "tegra_actmon",
708 NULL);
679 709
680 return 0; 710 return 0;
681} 711}
@@ -683,6 +713,19 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
683static int tegra_devfreq_remove(struct platform_device *pdev) 713static int tegra_devfreq_remove(struct platform_device *pdev)
684{ 714{
685 struct tegra_devfreq *tegra = platform_get_drvdata(pdev); 715 struct tegra_devfreq *tegra = platform_get_drvdata(pdev);
716 int irq = platform_get_irq(pdev, 0);
717 u32 val;
718 unsigned int i;
719
720 for (i = 0; i < ARRAY_SIZE(actmon_device_configs); i++) {
721 val = device_readl(&tegra->devices[i], ACTMON_DEV_CTRL);
722 val &= ~ACTMON_DEV_CTRL_ENB;
723 device_writel(&tegra->devices[i], val, ACTMON_DEV_CTRL);
724 }
725
726 actmon_write_barrier(tegra);
727
728 devm_free_irq(&pdev->dev, irq, tegra);
686 729
687 clk_notifier_unregister(tegra->emc_clock, &tegra->rate_change_nb); 730 clk_notifier_unregister(tegra->emc_clock, &tegra->rate_change_nb);
688 731
@@ -691,28 +734,52 @@ static int tegra_devfreq_remove(struct platform_device *pdev)
691 return 0; 734 return 0;
692} 735}
693 736
694static SIMPLE_DEV_PM_OPS(tegra_devfreq_pm_ops, 737static const struct of_device_id tegra_devfreq_of_match[] = {
695 tegra_devfreq_suspend,
696 tegra_devfreq_resume);
697
698static struct of_device_id tegra_devfreq_of_match[] = {
699 { .compatible = "nvidia,tegra124-actmon" }, 738 { .compatible = "nvidia,tegra124-actmon" },
700 { }, 739 { },
701}; 740};
702 741
742MODULE_DEVICE_TABLE(of, tegra_devfreq_of_match);
743
703static struct platform_driver tegra_devfreq_driver = { 744static struct platform_driver tegra_devfreq_driver = {
704 .probe = tegra_devfreq_probe, 745 .probe = tegra_devfreq_probe,
705 .remove = tegra_devfreq_remove, 746 .remove = tegra_devfreq_remove,
706 .driver = { 747 .driver = {
707 .name = "tegra-devfreq", 748 .name = "tegra-devfreq",
708 .owner = THIS_MODULE,
709 .of_match_table = tegra_devfreq_of_match, 749 .of_match_table = tegra_devfreq_of_match,
710 .pm = &tegra_devfreq_pm_ops,
711 }, 750 },
712}; 751};
713module_platform_driver(tegra_devfreq_driver);
714 752
715MODULE_LICENSE("GPL"); 753static int __init tegra_devfreq_init(void)
754{
755 int ret = 0;
756
757 ret = devfreq_add_governor(&tegra_devfreq_governor);
758 if (ret) {
759 pr_err("%s: failed to add governor: %d\n", __func__, ret);
760 return ret;
761 }
762
763 ret = platform_driver_register(&tegra_devfreq_driver);
764 if (ret)
765 devfreq_remove_governor(&tegra_devfreq_governor);
766
767 return ret;
768}
769module_init(tegra_devfreq_init)
770
771static void __exit tegra_devfreq_exit(void)
772{
773 int ret = 0;
774
775 platform_driver_unregister(&tegra_devfreq_driver);
776
777 ret = devfreq_remove_governor(&tegra_devfreq_governor);
778 if (ret)
779 pr_err("%s: failed to remove governor: %d\n", __func__, ret);
780}
781module_exit(tegra_devfreq_exit)
782
783MODULE_LICENSE("GPL v2");
716MODULE_DESCRIPTION("Tegra devfreq driver"); 784MODULE_DESCRIPTION("Tegra devfreq driver");
717MODULE_AUTHOR("Tomeu Vizoso <tomeu.vizoso@collabora.com>"); 785MODULE_AUTHOR("Tomeu Vizoso <tomeu.vizoso@collabora.com>");
718MODULE_DEVICE_TABLE(of, tegra_devfreq_of_match);