@@ -171,6 +171,8 @@ struct tegra_devfreq {
171
171
struct tegra_devfreq_device devices [ARRAY_SIZE (actmon_device_configs )];
172
172
173
173
unsigned int irq ;
174
+
175
+ bool started ;
174
176
};
175
177
176
178
struct tegra_actmon_emc_ratio {
@@ -209,18 +211,26 @@ static void device_writel(struct tegra_devfreq_device *dev, u32 val,
209
211
writel_relaxed (val , dev -> regs + offset );
210
212
}
211
213
212
- static unsigned long do_percent (unsigned long val , unsigned int pct )
214
+ static unsigned long do_percent (unsigned long long val , unsigned int pct )
213
215
{
214
- return val * pct / 100 ;
216
+ val = val * pct ;
217
+ do_div (val , 100 );
218
+
219
+ /*
220
+ * High freq + high boosting percent + large polling interval are
221
+ * resulting in integer overflow when watermarks are calculated.
222
+ */
223
+ return min_t (u64 , val , U32_MAX );
215
224
}
216
225
217
226
static void tegra_devfreq_update_avg_wmark (struct tegra_devfreq * tegra ,
218
227
struct tegra_devfreq_device * dev )
219
228
{
220
- u32 avg = dev -> avg_count ;
221
229
u32 avg_band_freq = tegra -> max_freq * ACTMON_DEFAULT_AVG_BAND / KHZ ;
222
- u32 band = avg_band_freq * ACTMON_SAMPLING_PERIOD ;
230
+ u32 band = avg_band_freq * tegra -> devfreq -> profile -> polling_ms ;
231
+ u32 avg ;
223
232
233
+ avg = min (dev -> avg_count , U32_MAX - band );
224
234
device_writel (dev , avg + band , ACTMON_DEV_AVG_UPPER_WMARK );
225
235
226
236
avg = max (dev -> avg_count , band );
@@ -230,7 +240,7 @@ static void tegra_devfreq_update_avg_wmark(struct tegra_devfreq *tegra,
230
240
static void tegra_devfreq_update_wmark (struct tegra_devfreq * tegra ,
231
241
struct tegra_devfreq_device * dev )
232
242
{
233
- u32 val = tegra -> cur_freq * ACTMON_SAMPLING_PERIOD ;
243
+ u32 val = tegra -> cur_freq * tegra -> devfreq -> profile -> polling_ms ;
234
244
235
245
device_writel (dev , do_percent (val , dev -> config -> boost_up_threshold ),
236
246
ACTMON_DEV_UPPER_WMARK );
@@ -309,7 +319,7 @@ static unsigned long actmon_device_target_freq(struct tegra_devfreq *tegra,
309
319
unsigned int avg_sustain_coef ;
310
320
unsigned long target_freq ;
311
321
312
- target_freq = dev -> avg_count / ACTMON_SAMPLING_PERIOD ;
322
+ target_freq = dev -> avg_count / tegra -> devfreq -> profile -> polling_ms ;
313
323
avg_sustain_coef = 100 * 100 / dev -> config -> boost_up_threshold ;
314
324
target_freq = do_percent (target_freq , avg_sustain_coef );
315
325
@@ -469,7 +479,7 @@ static void tegra_actmon_configure_device(struct tegra_devfreq *tegra,
469
479
470
480
dev -> target_freq = tegra -> cur_freq ;
471
481
472
- dev -> avg_count = tegra -> cur_freq * ACTMON_SAMPLING_PERIOD ;
482
+ dev -> avg_count = tegra -> cur_freq * tegra -> devfreq -> profile -> polling_ms ;
473
483
device_writel (dev , dev -> avg_count , ACTMON_DEV_INIT_AVG );
474
484
475
485
tegra_devfreq_update_avg_wmark (tegra , dev );
@@ -505,12 +515,15 @@ static void tegra_actmon_stop_devices(struct tegra_devfreq *tegra)
505
515
}
506
516
}
507
517
508
- static int tegra_actmon_start (struct tegra_devfreq * tegra )
518
+ static int tegra_actmon_resume (struct tegra_devfreq * tegra )
509
519
{
510
520
unsigned int i ;
511
521
int err ;
512
522
513
- actmon_writel (tegra , ACTMON_SAMPLING_PERIOD - 1 ,
523
+ if (!tegra -> devfreq -> profile -> polling_ms || !tegra -> started )
524
+ return 0 ;
525
+
526
+ actmon_writel (tegra , tegra -> devfreq -> profile -> polling_ms - 1 ,
514
527
ACTMON_GLB_PERIOD_CTRL );
515
528
516
529
/*
@@ -558,8 +571,26 @@ static int tegra_actmon_start(struct tegra_devfreq *tegra)
558
571
return err ;
559
572
}
560
573
561
- static void tegra_actmon_stop (struct tegra_devfreq * tegra )
574
+ static int tegra_actmon_start (struct tegra_devfreq * tegra )
562
575
{
576
+ int ret = 0 ;
577
+
578
+ if (!tegra -> started ) {
579
+ tegra -> started = true;
580
+
581
+ ret = tegra_actmon_resume (tegra );
582
+ if (ret )
583
+ tegra -> started = false;
584
+ }
585
+
586
+ return ret ;
587
+ }
588
+
589
+ static void tegra_actmon_pause (struct tegra_devfreq * tegra )
590
+ {
591
+ if (!tegra -> devfreq -> profile -> polling_ms || !tegra -> started )
592
+ return ;
593
+
563
594
disable_irq (tegra -> irq );
564
595
565
596
cpufreq_unregister_notifier (& tegra -> cpu_rate_change_nb ,
@@ -572,6 +603,12 @@ static void tegra_actmon_stop(struct tegra_devfreq *tegra)
572
603
clk_notifier_unregister (tegra -> emc_clock , & tegra -> clk_rate_change_nb );
573
604
}
574
605
606
+ static void tegra_actmon_stop (struct tegra_devfreq * tegra )
607
+ {
608
+ tegra_actmon_pause (tegra );
609
+ tegra -> started = false;
610
+ }
611
+
575
612
static int tegra_devfreq_target (struct device * dev , unsigned long * freq ,
576
613
u32 flags )
577
614
{
@@ -629,15 +666,15 @@ static int tegra_devfreq_get_dev_status(struct device *dev,
629
666
stat -> busy_time *= 100 / BUS_SATURATION_RATIO ;
630
667
631
668
/* Number of cycles in a sampling period */
632
- stat -> total_time = ACTMON_SAMPLING_PERIOD * cur_freq ;
669
+ stat -> total_time = tegra -> devfreq -> profile -> polling_ms * cur_freq ;
633
670
634
671
stat -> busy_time = min (stat -> busy_time , stat -> total_time );
635
672
636
673
return 0 ;
637
674
}
638
675
639
676
static struct devfreq_dev_profile tegra_devfreq_profile = {
640
- .polling_ms = 0 ,
677
+ .polling_ms = ACTMON_SAMPLING_PERIOD ,
641
678
.target = tegra_devfreq_target ,
642
679
.get_dev_status = tegra_devfreq_get_dev_status ,
643
680
};
@@ -677,6 +714,7 @@ static int tegra_governor_event_handler(struct devfreq *devfreq,
677
714
unsigned int event , void * data )
678
715
{
679
716
struct tegra_devfreq * tegra = dev_get_drvdata (devfreq -> dev .parent );
717
+ unsigned int * new_delay = data ;
680
718
int ret = 0 ;
681
719
682
720
/*
@@ -696,6 +734,21 @@ static int tegra_governor_event_handler(struct devfreq *devfreq,
696
734
devfreq_monitor_stop (devfreq );
697
735
break ;
698
736
737
+ case DEVFREQ_GOV_INTERVAL :
738
+ /*
739
+ * ACTMON hardware supports up to 256 milliseconds for the
740
+ * sampling period.
741
+ */
742
+ if (* new_delay > 256 ) {
743
+ ret = - EINVAL ;
744
+ break ;
745
+ }
746
+
747
+ tegra_actmon_pause (tegra );
748
+ devfreq_interval_update (devfreq , new_delay );
749
+ ret = tegra_actmon_resume (tegra );
750
+ break ;
751
+
699
752
case DEVFREQ_GOV_SUSPEND :
700
753
tegra_actmon_stop (tegra );
701
754
devfreq_monitor_suspend (devfreq );
@@ -715,6 +768,7 @@ static struct devfreq_governor tegra_devfreq_governor = {
715
768
.get_target_freq = tegra_governor_get_target ,
716
769
.event_handler = tegra_governor_event_handler ,
717
770
.immutable = true,
771
+ .interrupt_driven = true,
718
772
};
719
773
720
774
static int tegra_devfreq_probe (struct platform_device * pdev )
0 commit comments