import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / arm / mach-mt8127 / ca7_timer.c
1 #include <linux/init.h>
2 #include <linux/kernel.h>
3 #include <linux/delay.h>
4 #include <linux/smp.h>
5 #include <linux/jiffies.h>
6 #include <linux/clockchips.h>
7 #include <linux/interrupt.h>
8
9 #include <asm/localtimer.h>
10
11
12 #define read_cntfrq(cntfrq) \
13 do { \
14 __asm__ __volatile__( \
15 "MRC p15, 0, %0, c14, c0, 0\n" \
16 :"=r"(cntfrq) \
17 : \
18 :"memory"); \
19 } while (0)
20
21 #define change_cntfrq(cntfrq) \
22 do { \
23 __asm__ __volatile__( \
24 "MCR p15, 0, %0, c14, c0, 0\n" \
25 : \
26 :"r"(cntfrq)); \
27 } while (0)
28
29 #define read_cntkctl(cntkctl) \
30 do { \
31 __asm__ __volatile__( \
32 "MRC p15, 0, %0, c14, c1, 0\n" \
33 :"=r"(cntkctl) \
34 : \
35 :"memory"); \
36 } while (0)
37
38 #define read_cntpct(cntpct_lo, cntpct_hi) \
39 do { \
40 __asm__ __volatile__( \
41 "MRRC p15, 0, %0, %1, c14\n" \
42 :"=r"(cntpct_lo), "=r"(cntpct_hi) \
43 : \
44 :"memory"); \
45 } while (0)
46
47 #define read_cntvct(cntvct_lo, cntvct_hi) \
48 do { \
49 __asm__ __volatile__( \
50 "MRRC p15, 1, %0, %1, c14\n" \
51 :"=r"(cntvct_lo), "=r"(cntvct_hi) \
52 : \
53 :"memory"); \
54 } while (0)
55
56 #define read_cntp_ctl(cntp_ctl) \
57 do { \
58 __asm__ __volatile__( \
59 "MRC p15, 0, %0, c14, c2, 1\n" \
60 :"=r"(cntp_ctl) \
61 : \
62 :"memory"); \
63 } while (0)
64
65 #define write_cntp_ctl(cntp_ctl) \
66 do { \
67 __asm__ __volatile__( \
68 "MCR p15, 0, %0, c14, c2, 1\n" \
69 : \
70 :"r"(cntp_ctl)); \
71 } while (0)
72
73
74 #define read_cntp_cval(cntp_cval_lo, cntp_cval_hi) \
75 do { \
76 __asm__ __volatile__( \
77 "MRRC p15, 2, %0, %1, c14\n" \
78 :"=r"(cntp_cval_lo), "=r"(cntp_cval_hi) \
79 : \
80 :"memory"); \
81 } while (0)
82
83 #define write_cntp_cval(cntp_cval_lo, cntp_cval_hi) \
84 do { \
85 __asm__ __volatile__( \
86 "MCRR p15, 2, %0, %1, c14\n" \
87 : \
88 :"r"(cntp_cval_lo), "r"(cntp_cval_hi)); \
89 } while (0)
90
91 #define read_cntp_tval(cntp_tval) \
92 do { \
93 __asm__ __volatile__( \
94 "MRC p15, 0, %0, c14, c2, 0" \
95 :"=r"(cntp_tval) \
96 : \
97 :"memory"); \
98 } while (0)
99
100 #define write_cntp_tval(cntp_tval) \
101 do { \
102 __asm__ __volatile__( \
103 "MCR p15, 0, %0, c14, c2, 0\n" \
104 : \
105 :"r"(cntp_tval)); \
106 } while (0)
107
108
109 #define read_cntv_ctl(cntv_ctl) \
110 do { \
111 __asm__ __volatile__( \
112 "MRC p15, 0, %0, c14, c3, 1\n" \
113 :"=r"(cntv_ctl) \
114 : \
115 :"memory"); \
116 } while (0)
117
118 #define read_cntv_cval(cntv_cval_lo, cntv_cval_hi) \
119 do { \
120 __asm__ __volatile__( \
121 "MRRC p15, 3, %0, %1, c14\n" \
122 :"=r"(cntv_cval_lo), "=r"(cntv_cval_hi) \
123 : \
124 :"memory"); \
125 } while (0)
126
127 #define read_cntv_tval(cntv_tval) \
128 do { \
129 __asm__ __volatile__( \
130 "MRC p15, 0, %0, c14, c3, 0" \
131 :"=r"(cntv_tval) \
132 : \
133 :"memory"); \
134 } while (0)
135
136
137 #define CNTP_CTL_ENABLE (1 << 0)
138 #define CNTP_CTL_IMASK (1 << 1)
139 #define CNTP_CTL_ISTATUS (1 << 2)
140
141 #define MT_LOCAL_TIMER_DEBUG
142 static void save_localtimer_info(unsigned long evt, int ext);
143
144 static unsigned long generic_timer_rate;
145
146 static struct clock_event_device __percpu **timer_evt;
147 static int timer_ppi;
148
149 static void generic_timer_set_mode(enum clock_event_mode mode,
150 struct clock_event_device *clk)
151 {
152 unsigned int ctrl;
153
154 switch (mode) {
155 case CLOCK_EVT_MODE_ONESHOT:
156 ctrl = CNTP_CTL_ENABLE;
157 break;
158 case CLOCK_EVT_MODE_PERIODIC:
159 case CLOCK_EVT_MODE_UNUSED:
160 case CLOCK_EVT_MODE_SHUTDOWN:
161 default:
162 ctrl = CNTP_CTL_IMASK;
163 }
164
165 write_cntp_ctl(ctrl);
166 }
167
168 static int generic_timer_set_next_event(unsigned long evt,
169 struct clock_event_device *unused)
170 {
171 write_cntp_tval(evt);
172 write_cntp_ctl(CNTP_CTL_ENABLE);
173
174 save_localtimer_info(evt, 0);
175
176 return 0;
177 }
178
179 int localtimer_set_next_event(unsigned long evt)
180 {
181 generic_timer_set_next_event(evt, NULL);
182
183 save_localtimer_info(evt, 1);
184
185 return 0;
186 }
187
188 unsigned long localtimer_get_counter(void)
189 {
190 unsigned long evt;
191 read_cntp_tval(evt);
192
193 return evt;
194 }
195
196
197 /*
198 * generic_timer_ack: checks for a local timer interrupt.
199 *
200 * If a local timer interrupt has occurred, acknowledge and return 1.
201 * Otherwise, return 0.
202 */
203 static int generic_timer_ack(void)
204 {
205 unsigned int cntp_ctl;
206 read_cntp_ctl(cntp_ctl);
207
208 if (cntp_ctl & CNTP_CTL_ISTATUS) {
209 write_cntp_ctl(CNTP_CTL_IMASK);
210 return 1;
211 }
212
213 printk("WARNING: Generic Timer CNTP_CTL = 0x%x\n", cntp_ctl);
214 return 0;
215 }
216
217 static void generic_timer_stop(struct clock_event_device *clk)
218 {
219 generic_timer_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
220 disable_percpu_irq(clk->irq);
221 }
222
223 static void __cpuinit generic_timer_calibrate_rate(void)
224 {
225 unsigned long count;
226 u64 waitjiffies;
227
228 /*
229 * If this is the first time round, we need to work out how fast
230 * the timer ticks
231 */
232 if (generic_timer_rate == 0) {
233 printk("Calibrating local timer... ");
234
235 /* Wait for a tick to start */
236 waitjiffies = get_jiffies_64() + 1;
237
238 while (get_jiffies_64() < waitjiffies)
239 udelay(10);
240
241 /* OK, now the tick has started, let's get the timer going */
242 waitjiffies += 5;
243
244 /* enable, no interrupt or reload */
245 write_cntp_ctl(CNTP_CTL_ENABLE | CNTP_CTL_IMASK);
246
247 /* maximum value */
248 write_cntp_tval(0xFFFFFFFFU);
249
250 while (get_jiffies_64() < waitjiffies)
251 udelay(10);
252
253 read_cntp_tval(count);
254 generic_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5);
255
256 printk("%lu.%02luMHz.\n", generic_timer_rate / 1000000,
257 (generic_timer_rate / 10000) % 100);
258 }
259 }
260
261 static irqreturn_t timer_handler(int irq, void *dev_id)
262 {
263 struct clock_event_device *evt = *(struct clock_event_device **)dev_id;
264 //#ifdef CONFIG_MT_SCHED_MONITOR
265 #if 0
266 // add timer event tracer for wdt debug
267 __raw_get_cpu_var(local_timer_ts) = sched_clock();
268 if (generic_timer_ack()) {
269 evt->event_handler(evt);
270 __raw_get_cpu_var(local_timer_te) = sched_clock();
271 return IRQ_HANDLED;
272 }
273 __raw_get_cpu_var(local_timer_te) = sched_clock();
274 return IRQ_NONE;
275 #else
276 if (generic_timer_ack()) {
277 evt->event_handler(evt);
278 return IRQ_HANDLED;
279 }
280 return IRQ_NONE;
281 #endif
282 }
283
284
285 /*
286 * Setup the local clock events for a CPU.
287 */
288 static int __cpuinit generic_timer_setup(struct clock_event_device *clk)
289 {
290 struct clock_event_device **this_cpu_clk;
291
292 pr_info("[ca7_timer]%s entry\n", __func__);
293 generic_timer_calibrate_rate();
294
295 write_cntp_ctl(0x0);
296
297 clk->name = "generic_timer";
298 clk->features = CLOCK_EVT_FEAT_ONESHOT;
299 clk->rating = 350;
300 clk->set_mode = generic_timer_set_mode;
301 clk->set_next_event = generic_timer_set_next_event;
302 clk->irq = timer_ppi;
303
304 this_cpu_clk = __this_cpu_ptr(timer_evt);
305 *this_cpu_clk = clk;
306
307 clockevents_config_and_register(clk, generic_timer_rate,
308 0xf, 0x7fffffff);
309
310 enable_percpu_irq(clk->irq, 0);
311
312 return 0;
313 }
314
315 static struct local_timer_ops generic_timer_ops __cpuinitdata = {
316 .setup = generic_timer_setup,
317 .stop = generic_timer_stop,
318 };
319
320 int __init generic_timer_register(void)
321 {
322 int err;
323
324 if (timer_evt)
325 return -EBUSY;
326
327 /* When TEE is enabled, change to use non-secure local timer */
328 #if defined(CONFIG_TRUSTONIC_TEE_SUPPORT) || defined(CONFIG_MTK_IN_HOUSE_TEE_SUPPORT)
329 timer_ppi = GIC_PPI_NS_PRIVATE_TIMER;
330 #else
331 timer_ppi = GIC_PPI_PRIVATE_TIMER;
332 #endif
333
334 timer_evt = alloc_percpu(struct clock_event_device *);
335
336 if (!timer_evt) {
337 err = -ENOMEM;
338 goto out_exit;
339 }
340
341 err = request_percpu_irq(timer_ppi, timer_handler, "timer", timer_evt);
342 if (err) {
343 pr_err("generic timer: can't register interrupt %d (%d)\n", timer_ppi, err);
344 goto out_free;
345 }
346
347 err = local_timer_register(&generic_timer_ops);
348 if (err)
349 goto out_irq;
350
351 return 0;
352
353 out_irq:
354 free_percpu_irq(timer_ppi, timer_evt);
355 out_free:
356 free_percpu(timer_evt);
357 timer_evt = NULL;
358 out_exit:
359 return err;
360 }
361
362 #ifdef MT_LOCAL_TIMER_DEBUG
363 #include <linux/sched.h>
364
365 struct localtimer_info {
366 unsigned long evt;
367 unsigned int ctrl;
368 int ext;
369 unsigned long long timestamp;
370 };
371
372 static struct localtimer_info save_data[NR_CPUS];
373
374 static void save_localtimer_info(unsigned long evt, int ext)
375 {
376 int cpu;
377 unsigned int ctrl;
378
379 cpu = smp_processor_id();
380 read_cntp_ctl(ctrl);
381
382 save_data[cpu].evt = evt;
383 save_data[cpu].ctrl = ctrl;
384 save_data[cpu].ext = ext;
385 save_data[cpu].timestamp = sched_clock();
386 }
387
388 int dump_localtimer_info(char* buffer, int size)
389 {
390 int i;
391 int len = 0;
392 #define LOCAL_LEN 256
393 char fmt[LOCAL_LEN];
394
395 unsigned int cntp_ctl;
396 unsigned int cntp_tval;
397 unsigned int cntp_cval_lo, cntp_cval_hi;
398 unsigned int cntpct_lo, cntpct_hi;
399
400 if (!buffer || size <= 1) {
401 return 0;
402 }
403
404 len += snprintf(fmt + len, LOCAL_LEN - len, "[localtimer]cpu evt ctl ext time\n");
405
406 for (i = 0; i < nr_cpu_ids; i++) {
407 len += snprintf(fmt + len, LOCAL_LEN - len, "%d %lx %x %d %llx\n",
408 i, save_data[i].evt, save_data[i].ctrl,
409 save_data[i].ext, save_data[i].timestamp);
410 }
411
412 read_cntp_ctl(cntp_ctl);
413 read_cntp_cval(cntp_cval_lo, cntp_cval_hi);
414 read_cntp_tval(cntp_tval);
415 read_cntpct(cntpct_lo, cntpct_hi);
416
417 len += snprintf(fmt + len, LOCAL_LEN - len, "cpu ctl tval cval pct\n");
418 len += snprintf(fmt + len, LOCAL_LEN - len,
419 "%d %x %x (%x,%x) (%x,%x)\n",
420 smp_processor_id(), cntp_ctl, cntp_tval,
421 cntp_cval_lo, cntp_cval_hi, cntpct_lo, cntpct_hi);
422
423 len = min(len, size - 1);
424 memcpy(buffer, fmt, len);
425 *(buffer + len) = '\0';
426
427 return len;
428 }
429 #else
430
431 static inline void save_localtimer_info(unsigned long evt, int ext)
432 {
433 return ;
434 }
435
436 int dump_localtimer_info(char* buffer, int size)
437 {
438 return 0;
439 }
440
441 #endif
442
443
444 #if 0
445
446 #include <linux/module.h>
447 #include <linux/spinlock.h>
448 #include <linux/proc_fs.h>
449 #include <linux/kthread.h>
450 #include <linux/err.h>
451
452 #include <asm/uaccess.h>
453 #include <mach/mt_gpt.h>
454
455 static int cpuid[NR_CPUS] = {0};
456 static struct completion notify[NR_CPUS];
457 static struct completion ack;
458 static unsigned int opcode = 0;
459 static unsigned int op1 = 0;
460 static unsigned int op2 = 0;
461
462 static DEFINE_MUTEX(opcode_lock);
463 static DEFINE_SPINLOCK(cpu_lock);
464
465
466 void dump_timer_regs(void)
467 {
468 #if 0
469 unsigned int cntfrq = 0xFFFFFFFF;
470 unsigned int cntkctl = 0xFFFFFFFF;
471 #endif
472 unsigned int cntpct_lo = 0xFFFFFFFF;
473 unsigned int cntpct_hi = 0xFFFFFFFF;
474 #if 0
475 unsigned int cntvct_lo = 0xFFFFFFFF;
476 unsigned int cntvct_hi = 0xFFFFFFFF;
477 #endif
478 unsigned int cntp_ctl = 0xFFFFFFFF;
479 unsigned int cntp_cval_lo = 0xFFFFFFFF;
480 unsigned int cntp_cval_hi = 0xFFFFFFFF;
481 unsigned int cntp_tval = 0xFFFFFFFF;
482 #if 0
483 unsigned int cntv_ctl = 0xFFFFFFFF;
484 unsigned int cntv_cval_lo = 0xFFFFFFFF;
485 unsigned int cntv_cval_hi = 0xFFFFFFFF;
486 unsigned int cntv_tval = 0xFFFFFFFF;
487 #endif
488
489 #if 0
490 read_cntfrq(cntfrq);
491 read_cntkctl(cntkctl);
492 #endif
493 read_cntpct(cntpct_lo, cntpct_hi);
494 #if 0
495 read_cntvct(cntvct_lo, cntvct_hi);
496 #endif
497 read_cntp_ctl(cntp_ctl);
498 read_cntp_cval(cntp_cval_lo, cntp_cval_hi);
499 read_cntp_tval(cntp_tval);
500 #if 0
501 read_cntv_ctl(cntv_ctl);
502 read_cntv_cval(cntv_cval_lo, cntv_cval_hi);
503 read_cntv_tval(cntv_tval);
504 #endif
505
506 #if 0
507 printk("[ca7_timer]0. cntfrq = 0x%x\n", cntfrq);
508 printk("[ca7_timer]1. cntkctl = 0x%x\n", cntkctl);
509 #endif
510 printk("[ca7_timer]2. cntpct_lo = 0x%08x, cntpct_hi = 0x%08x\n", cntpct_lo, cntpct_hi);
511 #if 0
512 printk("[ca7_timer]3. cntvct_lo = 0x%08x, cntvct_hi = 0x%08x\n", cntvct_lo, cntvct_hi);
513 #endif
514 printk("[ca7_timer]4. cntp_ctl = 0x%x\n", cntp_ctl);
515 printk("[ca7_timer]5. cntp_cval_lo = 0x%08x, cntp_cval_hi = 0x%08x\n", cntp_cval_lo, cntp_cval_hi);
516 printk("[ca7_timer]6. cntp_tval = 0x%08x\n", cntp_tval);
517 #if 0
518 printk("[ca7_timer]7. cntv_ctl = 0x%x\n", cntv_ctl);
519 printk("[ca7_timer]8. cntv_cval_lo = 0x%08x, cntv_cval_hi = 0x%08x\n", cntv_cval_lo, cntv_cval_hi);
520 printk("[ca7_timer]9. cntv_tval = 0x%08x\n", cntv_tval);
521 #endif
522 }
523
524
525 static int test_ack(void)
526 {
527 unsigned int cntp_ctl;
528 read_cntp_ctl(cntp_ctl);
529
530 printk("test_ack: CNTP_CTL = 0x%x\n", cntp_ctl);
531
532 if (cntp_ctl & CNTP_CTL_ISTATUS) {
533 write_cntp_ctl(CNTP_CTL_IMASK);
534 return 1;
535 }
536
537 return 0;
538 }
539
540 static irqreturn_t test_handler(int irq, void *dev_id)
541 {
542 if (test_ack()) {
543 //unsigned int pos = gpt_get_cnt(GPT2);
544 //printk("[generic_timer:%s]entry, pos=%lu\n", __func__, pos);
545 return IRQ_HANDLED;
546 }
547 return IRQ_NONE;
548 }
549
550
551 static void test_operation(void)
552 {
553 if (opcode == 0) {
554 dump_timer_regs();
555 } else if (opcode == 1) {
556 write_cntp_tval(op1);
557 write_cntp_ctl(op2);
558 }
559 }
560
561
562 static int local_timer_test(void *data)
563 {
564 int cpu = *(int*)data;
565
566 #if defined(CONFIG_TRUSTONIC_TEE_SUPPORT) || defined(CONFIG_MTK_IN_HOUSE_TEE_SUPPORT)
567 printk("[%s]: thread for cpu%d start\n", __func__, cpu);
568 enable_percpu_irq(GIC_PPI_PRIVATE_TIMER, 0);
569 enable_percpu_irq(GIC_PPI_NS_PRIVATE_TIMER, 0);
570 #else
571 printk("[%s]: thread for cpu%d start\n", __func__, cpu);
572 enable_percpu_irq(GIC_PPI_PRIVATE_TIMER, 0);
573 #endif
574
575 while (1) {
576 wait_for_completion(&notify[cpu]);
577 test_operation();
578 complete(&ack);
579 }
580
581 printk("[%s]: thread for cpu%d stop\n", __func__, cpu);
582 return 0;
583 }
584
585 void local_timer_test_init(void)
586 {
587 int err = 0, err2 = 0;
588 int i = 0;
589 unsigned char name[10] = {'\0'};
590 struct task_struct *thread[nr_cpu_ids];
591 static struct clock_event_device *evt;
592
593 err = request_gpt(GPT6, GPT_FREE_RUN, GPT_CLK_SRC_SYS, GPT_CLK_DIV_1, 0, NULL, 0);
594 if (err) {
595 printk(KERN_ERR "fail to request gpt, err=%d\n", err);
596 }
597
598 #if defined(CONFIG_TRUSTONIC_TEE_SUPPORT) || defined(CONFIG_MTK_IN_HOUSE_TEE_SUPPORT)
599 err = request_percpu_irq(GIC_PPI_PRIVATE_TIMER, test_handler, "timer", &evt);
600 err2 = request_percpu_irq(GIC_PPI_NS_PRIVATE_TIMER, timer_handler, "timer", timer_evt);
601 if (err && err2) {
602 printk(KERN_ERR "can't register interrupt %d, err=%d, %d, err=%d\n",
603 GIC_PPI_PRIVATE_TIMER, err, GIC_PPI_NS_PRIVATE_TIMER, err2);
604 }
605 #else
606 err = request_percpu_irq(GIC_PPI_PRIVATE_TIMER, test_handler, "timer", &evt);
607 if (err) {
608 printk(KERN_ERR "can't register interrupt %d, err=%d\n", GIC_PPI_PRIVATE_TIMER, err);
609 }
610 #endif
611
612 init_completion(&ack);
613 for (i = 0; i < nr_cpu_ids; i++) {
614 cpuid[i] = i;
615 init_completion(&notify[i]);
616 sprintf(name, "timer-%d", i);
617 thread[i] = kthread_create(local_timer_test, &cpuid[i], name);
618 if (IS_ERR(thread[i])) {
619 err = PTR_ERR(thread[i]);
620 thread[i] = NULL;
621 printk(KERN_ERR "[%s]: kthread_create %s fail(%d)\n", __func__, name, err);
622 return;
623 }
624 kthread_bind(thread[i], i);
625 wake_up_process(thread[i]);
626 }
627 }
628
629
630 static int local_timer_test_read(char *page, char **start, off_t off,
631 int count, int *eof, void *data)
632 {
633 char *p = page;
634 int len = 0;
635
636 p += sprintf(p, "********** ca7 timer debug help *********\n");
637 p += sprintf(p, "echo opcode cpumask > /proc/lttest\n");
638 p += sprintf(p, "opcode:\n");
639 p += sprintf(p, "0: dump register\n");
640 p += sprintf(p, "1: count down\n");
641 p += sprintf(p, "2: count up\n");
642
643 *start = page + off;
644
645 len = p - page;
646 if (len > off)
647 len -= off;
648 else
649 len = 0;
650
651 *eof = 1;
652
653 return len < count ? len : count;
654 }
655
656 static int local_timer_test_write(struct file *file, const char *buffer,
657 unsigned long count, void *data)
658 {
659 char desc[32];
660 int len = 0;
661
662 unsigned int i = 0;
663 unsigned int cpu = 0;
664
665 unsigned int mask = 0;
666
667 len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
668 if (copy_from_user(desc, buffer, len)) {
669 return 0;
670 }
671 desc[len] = '\0';
672
673 spin_lock(&cpu_lock);
674 cpu = smp_processor_id();
675 spin_unlock(&cpu_lock);
676 printk("[%s]trigger test on cpu%u\n", __func__, cpu);
677
678 mutex_lock(&opcode_lock);
679
680 opcode = 0;
681 op1 = 0;
682 op2 = 0;
683
684 sscanf(desc, "%u %x %x %x", &opcode, &mask, &op1, &op2);
685 printk("opcode=%u, mask=%x, op1=%x, op2=%x\n", opcode, mask, op1, op2);
686
687 for (i = 0; i < nr_cpu_ids; i++) {
688 if (mask & (0x1 << i)) {
689 complete(&notify[i]);
690 wait_for_completion(&ack);
691 }
692 }
693
694 mutex_unlock(&opcode_lock);
695
696 return count;
697 }
698
699
700 static int __init local_timer_test_mod_init(void)
701 {
702 struct proc_dir_entry *entry = NULL;
703
704 entry = create_proc_entry("lttest", S_IRUGO | S_IWUSR, NULL);
705 if (entry) {
706 entry->read_proc = local_timer_test_read;
707 entry->write_proc = local_timer_test_write;
708 }
709
710 local_timer_test_init();
711
712 return 0;
713 }
714
715 module_init(local_timer_test_mod_init);
716 #endif