aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/devfreq/tegra-devfreq.c
diff options
context:
space:
mode:
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);