ARM: tegra: clock: Add Tegra3 EMC activity monitor support
[linux-3.10.git] / arch / arm / mach-tegra / tegra3_actmon.c
1 /*
2  * Copyright (c) 2011, NVIDIA Corporation.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11  * more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
16  */
17
18 #include <linux/kernel.h>
19 #include <linux/spinlock.h>
20 #include <linux/err.h>
21 #include <linux/io.h>
22 #include <linux/clk.h>
23 #include <linux/clk/tegra.h>
24 #include <linux/interrupt.h>
25 #include <linux/suspend.h>
26 #include <linux/debugfs.h>
27 #include <linux/seq_file.h>
28 #include <linux/uaccess.h>
29 #include <linux/module.h>
30
31 #include <mach/irqs.h>
32
33 #include "clock.h"
34 #include "iomap.h"
35
36 #define ACTMON_GLB_STATUS                       0x00
37 #define ACTMON_GLB_PERIOD_CTRL                  0x04
38
39 #define ACTMON_DEV_CTRL                         0x00
40 #define ACTMON_DEV_CTRL_ENB                     (0x1 << 31)
41 #define ACTMON_DEV_CTRL_UP_WMARK_ENB            (0x1 << 30)
42 #define ACTMON_DEV_CTRL_DOWN_WMARK_ENB          (0x1 << 29)
43 #define ACTMON_DEV_CTRL_UP_WMARK_NUM_SHIFT      26
44 #define ACTMON_DEV_CTRL_UP_WMARK_NUM_MASK       (0x7 << 26)
45 #define ACTMON_DEV_CTRL_DOWN_WMARK_NUM_SHIFT    23
46 #define ACTMON_DEV_CTRL_DOWN_WMARK_NUM_MASK     (0x7 << 23)
47 #define ACTMON_DEV_CTRL_AVG_UP_WMARK_ENB        (0x1 << 21)
48 #define ACTMON_DEV_CTRL_AVG_DOWN_WMARK_ENB      (0x1 << 20)
49 #define ACTMON_DEV_CTRL_PERIODIC_ENB            (0x1 << 18)
50 #define ACTMON_DEV_CTRL_K_VAL_SHIFT             10
51 #define ACTMON_DEV_CTRL_K_VAL_MASK              (0x7 << 10)
52
53 #define ACTMON_DEV_UP_WMARK                     0x04
54 #define ACTMON_DEV_DOWN_WMARK                   0x08
55 #define ACTMON_DEV_INIT_AVG                     0x0c
56 #define ACTMON_DEV_AVG_UP_WMARK                 0x10
57 #define ACTMON_DEV_AVG_DOWN_WMARK                       0x14
58
59 #define ACTMON_DEV_COUNT_WEGHT                  0x18
60 #define ACTMON_DEV_COUNT                        0x1c
61 #define ACTMON_DEV_AVG_COUNT                    0x20
62
63 #define ACTMON_DEV_INTR_STATUS                  0x24
64 #define ACTMON_DEV_INTR_UP_WMARK                (0x1 << 31)
65 #define ACTMON_DEV_INTR_DOWN_WMARK              (0x1 << 30)
66 #define ACTMON_DEV_INTR_AVG_DOWN_WMARK          (0x1 << 25)
67 #define ACTMON_DEV_INTR_AVG_UP_WMARK            (0x1 << 24)
68
69 #define ACTMON_DEFAULT_AVG_WINDOW_LOG2          6
70
71 enum actmon_type {
72         ACTMON_LOAD_SAMPLER,
73         ACTMON_FREQ_SAMPLER,
74 };
75
76 enum actmon_state {
77         ACTMON_UNINITIALIZED = -1,
78         ACTMON_OFF = 0,
79         ACTMON_ON  = 1,
80         ACTMON_SUSPENDED = 2,
81 };
82
83 #define ACTMON_DEFAULT_SAMPLING_PERIOD          10
84 static u8 actmon_sampling_period;
85
86 static unsigned long actmon_clk_freq;
87
88
89 /* Units:
90  * - frequency in kHz
91  * - coefficients, and thresholds in %
92  * - sampling period in ms
93  * - window in sample periods (value = setting + 1)
94  */
95 struct actmon_dev {
96         u32             reg;
97         u32             glb_status_irq_mask;
98         const char      *dev_id;
99         const char      *con_id;
100         struct clk      *clk;
101
102         unsigned long   max_freq;
103         unsigned long   target_freq;
104         unsigned long   cur_freq;
105
106         unsigned long   avg_actv_freq;
107         unsigned long   avg_band_freq;
108         unsigned int    avg_sustain_coef;
109         u32             avg_count;
110
111         unsigned long   boost_freq;
112         unsigned long   boost_freq_step;
113         unsigned int    boost_up_coef;
114         unsigned int    boost_down_coef;
115         unsigned int    boost_up_threshold;
116         unsigned int    boost_down_threshold;
117
118         u8              up_wmark_window;
119         u8              down_wmark_window;
120         u8              avg_window_log2;
121         u32             count_weight;
122
123         enum actmon_type        type;
124         enum actmon_state       state;
125         enum actmon_state       saved_state;
126
127         spinlock_t      lock;
128
129         struct notifier_block   rate_change_nb;
130 };
131
132 static void __iomem *actmon_base = IO_ADDRESS(TEGRA_ACTMON_BASE);
133
134 static inline u32 actmon_readl(u32 offset)
135 {
136         return __raw_readl(actmon_base + offset);
137 }
138 static inline void actmon_writel(u32 val, u32 offset)
139 {
140         __raw_writel(val, actmon_base + offset);
141 }
142 static inline void actmon_wmb(void)
143 {
144         wmb();
145         actmon_readl(ACTMON_GLB_STATUS);
146 }
147
148 #define offs(x)         (dev->reg + x)
149
150 static inline unsigned long do_percent(unsigned long val, unsigned int pct)
151 {
152         return val * pct / 100;
153 }
154
155 static inline void actmon_dev_up_wmark_set(struct actmon_dev *dev)
156 {
157         u32 val;
158         unsigned long freq = (dev->type == ACTMON_FREQ_SAMPLER) ?
159                 dev->cur_freq : actmon_clk_freq;
160
161         val = freq * actmon_sampling_period;
162         actmon_writel(do_percent(val, dev->boost_up_threshold),
163                       offs(ACTMON_DEV_UP_WMARK));
164 }
165
166 static inline void actmon_dev_down_wmark_set(struct actmon_dev *dev)
167 {
168         u32 val;
169         unsigned long freq = (dev->type == ACTMON_FREQ_SAMPLER) ?
170                 dev->cur_freq : actmon_clk_freq;
171
172         val = freq * actmon_sampling_period;
173         actmon_writel(do_percent(val, dev->boost_down_threshold),
174                       offs(ACTMON_DEV_DOWN_WMARK));
175 }
176
177 static inline void actmon_dev_wmark_set(struct actmon_dev *dev)
178 {
179         u32 val;
180         unsigned long freq = (dev->type == ACTMON_FREQ_SAMPLER) ?
181                 dev->cur_freq : actmon_clk_freq;
182
183         val = freq * actmon_sampling_period;
184         actmon_writel(do_percent(val, dev->boost_up_threshold),
185                       offs(ACTMON_DEV_UP_WMARK));
186         actmon_writel(do_percent(val, dev->boost_down_threshold),
187                       offs(ACTMON_DEV_DOWN_WMARK));
188 }
189
190 static inline void actmon_dev_avg_wmark_set(struct actmon_dev *dev)
191 {
192         u32 avg = dev->avg_count;
193         u32 band = dev->avg_band_freq * actmon_sampling_period;
194
195         actmon_writel(avg + band, offs(ACTMON_DEV_AVG_UP_WMARK));
196         avg = max(avg, band);
197         actmon_writel(avg - band, offs(ACTMON_DEV_AVG_DOWN_WMARK));
198 }
199
200 /* Activity monitor sampling operations */
201 irqreturn_t actmon_dev_isr(int irq, void *dev_id)
202 {
203         u32 val;
204         unsigned long flags;
205         struct actmon_dev *dev = (struct actmon_dev *)dev_id;
206
207         val = actmon_readl(ACTMON_GLB_STATUS) & dev->glb_status_irq_mask;
208         if (!val)
209                 return IRQ_NONE;
210
211         spin_lock_irqsave(&dev->lock, flags);
212
213         dev->avg_count = actmon_readl(offs(ACTMON_DEV_AVG_COUNT));
214         actmon_dev_avg_wmark_set(dev);
215
216         val = actmon_readl(offs(ACTMON_DEV_INTR_STATUS));
217         if (val & ACTMON_DEV_INTR_UP_WMARK) {
218                 val = actmon_readl(offs(ACTMON_DEV_CTRL)) |
219                         ACTMON_DEV_CTRL_UP_WMARK_ENB |
220                         ACTMON_DEV_CTRL_DOWN_WMARK_ENB;
221
222                 dev->boost_freq = dev->boost_freq_step +
223                         do_percent(dev->boost_freq, dev->boost_up_coef);
224                 if (dev->boost_freq >= dev->max_freq) {
225                         dev->boost_freq = dev->max_freq;
226                         val &= ~ACTMON_DEV_CTRL_UP_WMARK_ENB;
227                 }
228                 actmon_writel(val, offs(ACTMON_DEV_CTRL));
229         } else if (val & ACTMON_DEV_INTR_DOWN_WMARK) {
230                 val = actmon_readl(offs(ACTMON_DEV_CTRL)) |
231                         ACTMON_DEV_CTRL_UP_WMARK_ENB |
232                         ACTMON_DEV_CTRL_DOWN_WMARK_ENB;
233
234                 dev->boost_freq =
235                         do_percent(dev->boost_freq, dev->boost_down_coef);
236                 if (dev->boost_freq < (dev->boost_freq_step >> 1)) {
237                         dev->boost_freq = 0;
238                         val &= ~ACTMON_DEV_CTRL_DOWN_WMARK_ENB;
239                 }
240                 actmon_writel(val, offs(ACTMON_DEV_CTRL));
241         }
242
243         actmon_writel(0xffffffff, offs(ACTMON_DEV_INTR_STATUS)); /* clr all */
244         actmon_wmb();
245
246         spin_unlock_irqrestore(&dev->lock, flags);
247         return IRQ_WAKE_THREAD;
248 }
249
250 irqreturn_t actmon_dev_fn(int irq, void *dev_id)
251 {
252         unsigned long flags;
253         unsigned long freq = 0;
254         struct actmon_dev *dev = (struct actmon_dev *)dev_id;
255
256         spin_lock_irqsave(&dev->lock, flags);
257
258         if (dev->state == ACTMON_ON) {
259                 if (dev->type == ACTMON_FREQ_SAMPLER) {
260                         freq = dev->avg_count / actmon_sampling_period;
261                 }
262                 else {
263                         u64 tmp = (u64)dev->avg_count * dev->cur_freq;
264                         freq = actmon_clk_freq * actmon_sampling_period;
265                         do_div(tmp, freq);
266                         freq = (u32)tmp;
267                 }
268
269                 dev->avg_actv_freq = freq;
270                 freq = do_percent(freq, dev->avg_sustain_coef);
271                 freq += dev->boost_freq;
272                 dev->target_freq = freq;
273         }
274         spin_unlock_irqrestore(&dev->lock, flags);
275
276         if (freq) {
277                 pr_debug("%s.%s(kHz): avg: %lu, target: %lu current: %lu\n",
278                         dev->dev_id, dev->con_id, dev->avg_actv_freq,
279                         dev->target_freq, dev->cur_freq);
280                 clk_set_rate(dev->clk, freq * 1000);
281         }
282         return IRQ_HANDLED;
283 }
284
285 static int actmon_rate_notify_cb(
286         struct notifier_block *nb, unsigned long rate, void *v)
287 {
288         unsigned long flags;
289         struct actmon_dev *dev = container_of(
290                 nb, struct actmon_dev, rate_change_nb);
291
292         spin_lock_irqsave(&dev->lock, flags);
293
294         dev->cur_freq = rate / 1000;
295         if (dev->type == ACTMON_FREQ_SAMPLER) {
296                 actmon_dev_wmark_set(dev);
297                 actmon_wmb();
298         }
299
300         spin_unlock_irqrestore(&dev->lock, flags);
301         return NOTIFY_OK;
302 };
303
304 /* Activity monitor configuration and control */
305 static void actmon_dev_configure(struct actmon_dev *dev, unsigned long freq)
306 {
307         u32 val;
308
309         dev->cur_freq = freq;
310         dev->target_freq = freq;
311         dev->avg_actv_freq = freq;
312
313         dev->avg_count = (dev->type == ACTMON_FREQ_SAMPLER) ?
314                 dev->cur_freq : actmon_clk_freq;
315         dev->avg_count *= actmon_sampling_period;
316         actmon_writel(dev->avg_count, offs(ACTMON_DEV_INIT_AVG));
317
318         BUG_ON(!dev->boost_up_threshold);
319         dev->avg_sustain_coef = 100 * 100 / dev->boost_up_threshold;
320         actmon_dev_avg_wmark_set(dev);
321         actmon_dev_wmark_set(dev);
322
323         actmon_writel(dev->count_weight, offs(ACTMON_DEV_COUNT_WEGHT));
324         actmon_writel(0xffffffff, offs(ACTMON_DEV_INTR_STATUS)); /* clr all */
325
326         val = ACTMON_DEV_CTRL_PERIODIC_ENB | ACTMON_DEV_CTRL_AVG_UP_WMARK_ENB |
327                 ACTMON_DEV_CTRL_AVG_DOWN_WMARK_ENB;
328         val |= ((dev->avg_window_log2 - 1) << ACTMON_DEV_CTRL_K_VAL_SHIFT) &
329                 ACTMON_DEV_CTRL_K_VAL_MASK;
330         val |= ((dev->down_wmark_window - 1) <<
331                 ACTMON_DEV_CTRL_DOWN_WMARK_NUM_SHIFT) &
332                 ACTMON_DEV_CTRL_DOWN_WMARK_NUM_MASK;
333         val |=  ((dev->up_wmark_window - 1) <<
334                 ACTMON_DEV_CTRL_UP_WMARK_NUM_SHIFT) &
335                 ACTMON_DEV_CTRL_UP_WMARK_NUM_MASK;
336         val |= ACTMON_DEV_CTRL_DOWN_WMARK_ENB | ACTMON_DEV_CTRL_UP_WMARK_ENB;
337         actmon_writel(val, offs(ACTMON_DEV_CTRL));
338         actmon_wmb();
339 }
340
341 static void actmon_dev_enable(struct actmon_dev *dev)
342 {
343         u32 val;
344         unsigned long flags;
345
346         spin_lock_irqsave(&dev->lock, flags);
347
348         if (dev->state == ACTMON_OFF) {
349                 dev->state = ACTMON_ON;
350
351                 val = actmon_readl(offs(ACTMON_DEV_CTRL));
352                 val |= ACTMON_DEV_CTRL_ENB;
353                 actmon_writel(val, offs(ACTMON_DEV_CTRL));
354                 actmon_wmb();
355         }
356         spin_unlock_irqrestore(&dev->lock, flags);
357 }
358
359 static void actmon_dev_disable(struct actmon_dev *dev)
360 {
361         u32 val;
362         unsigned long flags;
363
364         spin_lock_irqsave(&dev->lock, flags);
365
366         if (dev->state == ACTMON_ON) {
367                 dev->state = ACTMON_OFF;
368
369                 val = actmon_readl(offs(ACTMON_DEV_CTRL));
370                 val &= ~ACTMON_DEV_CTRL_ENB;
371                 actmon_writel(val, offs(ACTMON_DEV_CTRL));
372                 actmon_writel(0xffffffff, offs(ACTMON_DEV_INTR_STATUS));
373                 actmon_wmb();
374         }
375         spin_unlock_irqrestore(&dev->lock, flags);
376 }
377
378 static void actmon_dev_suspend(struct actmon_dev *dev)
379 {
380         u32 val;
381         unsigned long flags;
382
383         spin_lock_irqsave(&dev->lock, flags);
384
385         if ((dev->state == ACTMON_ON) || (dev->state == ACTMON_OFF)){
386                 dev->saved_state = dev->state;
387                 dev->state = ACTMON_SUSPENDED;
388
389                 val = actmon_readl(offs(ACTMON_DEV_CTRL));
390                 val &= ~ACTMON_DEV_CTRL_ENB;
391                 actmon_writel(val, offs(ACTMON_DEV_CTRL));
392                 actmon_writel(0xffffffff, offs(ACTMON_DEV_INTR_STATUS));
393                 actmon_wmb();
394         }
395         spin_unlock_irqrestore(&dev->lock, flags);
396 }
397
398 static void actmon_dev_resume(struct actmon_dev *dev)
399 {
400         u32 val;
401         unsigned long flags, freq;
402
403         spin_lock_irqsave(&dev->lock, flags);
404
405         if (dev->state == ACTMON_SUSPENDED) {
406                 freq = clk_get_rate(dev->clk) / 1000;
407                 actmon_dev_configure(dev, freq);
408                 dev->state = dev->saved_state;
409                 if (dev->state == ACTMON_ON) {
410                         val = actmon_readl(offs(ACTMON_DEV_CTRL));
411                         val |= ACTMON_DEV_CTRL_ENB;
412                         actmon_writel(val, offs(ACTMON_DEV_CTRL));
413                         actmon_wmb();
414                 }
415         }
416         spin_unlock_irqrestore(&dev->lock, flags);
417 }
418
419 static int __init actmon_dev_init(struct actmon_dev *dev)
420 {
421         int ret;
422         struct clk *p;
423         unsigned long freq;
424
425         spin_lock_init(&dev->lock);
426
427         dev->clk = clk_get_sys(dev->dev_id, dev->con_id);
428         if (IS_ERR(dev->clk)) {
429                 pr_err("Failed to find %s.%s clock\n",
430                        dev->dev_id, dev->con_id);
431                 return -ENODEV;
432         }
433         dev->max_freq = clk_get_max_rate(dev->clk) / 1000;
434         freq = clk_get_rate(dev->clk) / 1000;
435         actmon_dev_configure(dev, freq);
436
437         /* actmon device controls shared bus user clock, but rate
438            change notification should come from bus clock itself */
439         p = clk_get_parent(dev->clk);
440         BUG_ON(!p);
441
442         if (dev->rate_change_nb.notifier_call) {
443                 ret = tegra_register_clk_rate_notifier(p, &dev->rate_change_nb);
444                 if (ret) {
445                         pr_err("Failed to register %s rate change notifier"
446                                " for %s\n", p->name, dev->dev_id);
447                         return ret;
448                 }
449         }
450
451         ret = request_threaded_irq(INT_ACTMON, actmon_dev_isr, actmon_dev_fn,
452                                    IRQF_SHARED, dev->dev_id, dev);
453         if (ret) {
454                 pr_err("Failed irq %d request for %s.%s\n",
455                        INT_ACTMON, dev->dev_id, dev->con_id);
456                 tegra_unregister_clk_rate_notifier(p, &dev->rate_change_nb);
457                 return ret;
458         }
459
460         dev->state = ACTMON_OFF;
461         actmon_dev_enable(dev);
462         clk_enable(dev->clk);
463         return 0;
464 }
465
466 /* EMC activity monitor: frequency sampling device */
467 static struct actmon_dev actmon_dev_emc = {
468         .reg    = 0x1c0,
469         .glb_status_irq_mask = (0x1 << 26),
470         .dev_id = "tegra_actmon",
471         .con_id = "emc",
472
473         .avg_band_freq          = 3000,
474
475         .boost_freq_step        = 16000,
476         .boost_up_coef          = 200,
477         .boost_down_coef        = 50,
478         .boost_up_threshold     = 60,
479         .boost_down_threshold   = 40,
480
481         .up_wmark_window        = 1,
482         .down_wmark_window      = 3,
483         .avg_window_log2        = ACTMON_DEFAULT_AVG_WINDOW_LOG2,
484         .count_weight           = 0x200,
485
486         .type                   = ACTMON_FREQ_SAMPLER,
487         .state                  = ACTMON_UNINITIALIZED,
488
489         .rate_change_nb = {
490                 .notifier_call = actmon_rate_notify_cb,
491         },
492 };
493
494 static struct actmon_dev *actmon_devices[] = {
495         &actmon_dev_emc,
496 };
497
498 /* Activity monitor suspend/resume */
499 static int actmon_pm_notify(struct notifier_block *nb,
500                             unsigned long event, void *data)
501 {
502         int i;
503
504         switch (event) {
505         case PM_SUSPEND_PREPARE:
506                 for (i = 0; i < ARRAY_SIZE(actmon_devices); i++)
507                         actmon_dev_suspend(actmon_devices[i]);
508                 break;
509         case PM_POST_SUSPEND:
510                 for (i = 0; i < ARRAY_SIZE(actmon_devices); i++)
511                         actmon_dev_resume(actmon_devices[i]);
512                 break;
513         }
514
515         return NOTIFY_OK;
516 };
517
518 static struct notifier_block actmon_pm_nb = {
519         .notifier_call = actmon_pm_notify,
520 };
521
522 #ifdef CONFIG_DEBUG_FS
523
524 #define RW_MODE (S_IWUSR | S_IRUGO)
525 #define RO_MODE S_IRUGO
526
527 static struct dentry *clk_debugfs_root;
528
529 static int type_show(struct seq_file *s, void *data)
530 {
531         struct actmon_dev *dev = s->private;
532
533         seq_printf(s, "%s\n", (dev->type == ACTMON_LOAD_SAMPLER) ?
534                    "Load Activity Monitor" : "Frequency Activity Monitor");
535         return 0;
536 }
537 static int type_open(struct inode *inode, struct file *file)
538 {
539         return single_open(file, type_show, inode->i_private);
540 }
541 static const struct file_operations type_fops = {
542         .open           = type_open,
543         .read           = seq_read,
544         .llseek         = seq_lseek,
545         .release        = single_release,
546 };
547
548 static int step_get(void *data, u64 *val)
549 {
550         struct actmon_dev *dev = data;
551         *val = dev->boost_freq_step * 100 / dev->max_freq;
552         return 0;
553 }
554 static int step_set(void *data, u64 val)
555 {
556         unsigned long flags;
557         struct actmon_dev *dev = data;
558
559         if (val > 100)
560                 val = 100;
561
562         spin_lock_irqsave(&dev->lock, flags);
563         dev->boost_freq_step = do_percent(dev->max_freq, (unsigned int)val);
564         spin_unlock_irqrestore(&dev->lock, flags);
565         return 0;
566 }
567 DEFINE_SIMPLE_ATTRIBUTE(step_fops, step_get, step_set, "%llu\n");
568
569 static int up_threshold_get(void *data, u64 *val)
570 {
571         struct actmon_dev *dev = data;
572         *val = dev->boost_up_threshold;
573         return 0;
574 }
575 static int up_threshold_set(void *data, u64 val)
576 {
577         unsigned long flags;
578         struct actmon_dev *dev = data;
579         unsigned int up_threshold = (unsigned int)val;
580
581         if (up_threshold > 100)
582                 up_threshold = 100;
583
584         spin_lock_irqsave(&dev->lock, flags);
585
586         if (up_threshold <= dev->boost_down_threshold)
587                 up_threshold = dev->boost_down_threshold;
588         if (up_threshold)
589                 dev->avg_sustain_coef = 100 * 100 / up_threshold;
590         dev->boost_up_threshold = up_threshold;
591
592         actmon_dev_up_wmark_set(dev);
593         actmon_wmb();
594
595         spin_unlock_irqrestore(&dev->lock, flags);
596         return 0;
597 }
598 DEFINE_SIMPLE_ATTRIBUTE(up_threshold_fops, up_threshold_get,
599                         up_threshold_set, "%llu\n");
600
601 static int down_threshold_get(void *data, u64 *val)
602 {
603         struct actmon_dev *dev = data;
604         *val = dev->boost_down_threshold;
605         return 0;
606 }
607 static int down_threshold_set(void *data, u64 val)
608 {
609         unsigned long flags;
610         struct actmon_dev *dev = data;
611         unsigned int down_threshold = (unsigned int)val;
612
613         if (down_threshold < 0)
614                 down_threshold = 0;
615
616         spin_lock_irqsave(&dev->lock, flags);
617
618         if (down_threshold >= dev->boost_up_threshold)
619                 down_threshold = dev->boost_up_threshold;
620         dev->boost_down_threshold = down_threshold;
621
622         actmon_dev_down_wmark_set(dev);
623         actmon_wmb();
624
625         spin_unlock_irqrestore(&dev->lock, flags);
626         return 0;
627 }
628 DEFINE_SIMPLE_ATTRIBUTE(down_threshold_fops, down_threshold_get,
629                         down_threshold_set, "%llu\n");
630
631 static int state_get(void *data, u64 *val)
632 {
633         struct actmon_dev *dev = data;
634         *val = dev->state;
635         return 0;
636 }
637 static int state_set(void *data, u64 val)
638 {
639         struct actmon_dev *dev = data;
640
641         if (val)
642                 actmon_dev_enable(dev);
643         else
644                 actmon_dev_disable(dev);
645         return 0;
646 }
647 DEFINE_SIMPLE_ATTRIBUTE(state_fops, state_get, state_set, "%llu\n");
648
649 static int period_get(void *data, u64 *val)
650 {
651         *val = actmon_sampling_period;
652         return 0;
653 }
654 static int period_set(void *data, u64 val)
655 {
656         u8 period = (u8)val;
657
658         if (period) {
659                 actmon_sampling_period = period;
660                 actmon_writel(period - 1, ACTMON_GLB_PERIOD_CTRL);
661                 /* FIXME: update up/down wm for load sampler */
662                 return 0;
663         }
664         return -EINVAL;
665 }
666 DEFINE_SIMPLE_ATTRIBUTE(period_fops, period_get, period_set, "%llu\n");
667
668
669 static int actmon_debugfs_create_dev(struct actmon_dev *dev)
670 {
671         struct dentry *dir, *d;
672
673         if (dev->state == ACTMON_UNINITIALIZED)
674                 return 0;
675
676         dir = debugfs_create_dir(dev->con_id, clk_debugfs_root);
677         if (!dir)
678                 return -ENOMEM;
679
680         d = debugfs_create_file(
681                 "actv_type", RO_MODE, dir, dev, &type_fops);
682         if (!d)
683                 return -ENOMEM;
684
685         d = debugfs_create_u32(
686                 "avg_activity", RO_MODE, dir, (u32 *)&dev->avg_actv_freq);
687         if (!d)
688                 return -ENOMEM;
689
690         d = debugfs_create_file(
691                 "boost_step", RW_MODE, dir, dev, &step_fops);
692         if (!d)
693                 return -ENOMEM;
694
695         d = debugfs_create_u32(
696                 "boost_rate_dec", RW_MODE, dir, (u32 *)&dev->boost_down_coef);
697         if (!d)
698                 return -ENOMEM;
699
700         d = debugfs_create_u32(
701                 "boost_rate_inc", RW_MODE, dir, (u32 *)&dev->boost_up_coef);
702         if (!d)
703                 return -ENOMEM;
704
705         d = debugfs_create_file(
706                 "boost_threshold_dn", RW_MODE, dir, dev, &down_threshold_fops);
707         if (!d)
708                 return -ENOMEM;
709
710         d = debugfs_create_file(
711                 "boost_threshold_up", RW_MODE, dir, dev, &up_threshold_fops);
712         if (!d)
713                 return -ENOMEM;
714
715         d = debugfs_create_file(
716                 "state", RW_MODE, dir, dev, &state_fops);
717         if (!d)
718                 return -ENOMEM;
719
720         return 0;
721 }
722
723 static int __init actmon_debugfs_init(void)
724 {
725         int i;
726         int ret = -ENOMEM;
727         struct dentry *d;
728
729         d = debugfs_create_dir("tegra_actmon", NULL);
730         if (!d)
731                 return ret;
732         clk_debugfs_root = d;
733
734         d = debugfs_create_file("period", RW_MODE, d, NULL, &period_fops);
735         if (!d)
736                 goto err_out;
737
738         for (i = 0; i < ARRAY_SIZE(actmon_devices); i++) {
739                 ret = actmon_debugfs_create_dev(actmon_devices[i]);
740                 if (ret)
741                         goto err_out;
742         }
743         return 0;
744
745 err_out:
746         debugfs_remove_recursive(clk_debugfs_root);
747         return ret;
748 }
749
750 #endif
751
752 static int __init tegra_actmon_init(void)
753 {
754         int i, ret;
755         struct clk *c = tegra_get_clock_by_name("actmon");
756
757         if (!c) {
758                 pr_err("%s: Failed to find actmon clock\n", __func__);
759                 return 0;
760         }
761         actmon_clk_freq = clk_get_rate(c) / 1000;
762         ret = clk_enable(c);
763         if (ret) {
764                 pr_err("%s: Failed to enable actmon clock\n", __func__);
765                 return 0;
766         }
767         actmon_sampling_period = ACTMON_DEFAULT_SAMPLING_PERIOD;
768         actmon_writel(actmon_sampling_period - 1, ACTMON_GLB_PERIOD_CTRL);
769
770         for (i = 0; i < ARRAY_SIZE(actmon_devices); i++) {
771                 ret = actmon_dev_init(actmon_devices[i]);
772                 pr_info("%s.%s: %s initialization (%d)\n",
773                         actmon_devices[i]->dev_id, actmon_devices[i]->con_id,
774                         ret ? "Failed" : "Completed", ret);
775         }
776         register_pm_notifier(&actmon_pm_nb);
777
778 #ifdef CONFIG_DEBUG_FS
779         actmon_debugfs_init();
780 #endif
781         return 0;
782 }
783 late_initcall(tegra_actmon_init);