• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * drivers/soc/rockchip/rk_fiq_debugger.c
3  *
4  * Serial Debugger Interface for Rockchip
5  *
6  * Copyright (C) 2012 ROCKCHIP, Inc.
7  * Copyright (C) 2008 Google, Inc.
8  *
9  * This software is licensed under the terms of the GNU General Public
10  * License version 2, as published by the Free Software Foundation, and
11  * may be copied, distributed, and modified under those terms.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  */
18 
19 #include <stdarg.h>
20 #include <linux/cpu.h>
21 #include <linux/cpu_pm.h>
22 #include <linux/module.h>
23 #include <linux/io.h>
24 #include <linux/of.h>
25 #include <linux/of_address.h>
26 #include <linux/of_irq.h>
27 #include <linux/interrupt.h>
28 #include <linux/clk.h>
29 #include <linux/platform_device.h>
30 #include <linux/irq.h>
31 #include <linux/serial_reg.h>
32 #include <linux/slab.h>
33 #include <linux/stacktrace.h>
34 #include <linux/uaccess.h>
35 #include <linux/kfifo.h>
36 #include <linux/kthread.h>
37 #include <linux/sched/rt.h>
38 #include <../staging/android/fiq_debugger/fiq_debugger.h>
39 #include <linux/irqchip/arm-gic.h>
40 #include <linux/clk.h>
41 #include <linux/delay.h>
42 #include <linux/soc/rockchip/rk_fiq_debugger.h>
43 #include <linux/console.h>
44 
45 #ifdef CONFIG_FIQ_DEBUGGER_TRUST_ZONE
46 #include <linux/rockchip/rockchip_sip.h>
47 #endif
48 
49 #define UART_USR 0x1f                   /* In: UART Status Register */
50 #define UART_USR_RX_FIFO_FULL 0x10      /* Receive FIFO full */
51 #define UART_USR_RX_FIFO_NOT_EMPTY 0x08 /* Receive FIFO not empty */
52 #define UART_USR_TX_FIFO_EMPTY 0x04     /* Transmit FIFO empty */
53 #define UART_USR_TX_FIFO_NOT_FULL 0x02  /* Transmit FIFO not full */
54 #define UART_USR_BUSY 0x01              /* UART busy indicator */
55 #define UART_SRR 0x22                   /* software reset register */
56 
57 struct rk_fiq_debugger {
58     int irq;
59     int baudrate;
60     struct fiq_debugger_pdata pdata;
61     void __iomem *debug_port_base;
62     bool break_seen;
63 #ifdef CONFIG_RK_CONSOLE_THREAD
64     struct task_struct *console_task;
65 #endif
66 };
67 
68 static int rk_fiq_debugger_id;
69 static int serial_hwirq;
70 
71 #ifdef CONFIG_FIQ_DEBUGGER_TRUST_ZONE
72 static bool tf_fiq_sup;
73 #endif
74 
rk_fiq_write(struct rk_fiq_debugger * t,unsigned int val,unsigned int off)75 static inline void rk_fiq_write(struct rk_fiq_debugger *t, unsigned int val, unsigned int off)
76 {
77     __raw_writel(val, t->debug_port_base + off * 0x04);
78 }
79 
rk_fiq_read(struct rk_fiq_debugger * t,unsigned int off)80 static inline unsigned int rk_fiq_read(struct rk_fiq_debugger *t, unsigned int off)
81 {
82     return __raw_readl(t->debug_port_base + off * 0x04);
83 }
84 
rk_fiq_read_lsr(struct rk_fiq_debugger * t)85 static inline unsigned int rk_fiq_read_lsr(struct rk_fiq_debugger *t)
86 {
87     unsigned int lsr;
88 
89     lsr = rk_fiq_read(t, UART_LSR);
90     if (lsr & UART_LSR_BI) {
91         t->break_seen = true;
92     }
93 
94     return lsr;
95 }
96 
debug_port_init(struct platform_device * pdev)97 static int debug_port_init(struct platform_device *pdev)
98 {
99     int dll = 0, dlm = 0;
100     struct rk_fiq_debugger *t;
101 
102     console_lock();
103 
104     t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
105 
106     if (rk_fiq_read(t, UART_LSR) & UART_LSR_DR) {
107         (void)rk_fiq_read(t, UART_RX);
108     }
109 
110     switch (t->baudrate) {
111         case 0x16E360:
112             dll = 0x1;
113             break;
114         case 0x1C200:
115         default:
116             dll = 0xd;
117             break;
118     }
119     /* reset uart */
120     rk_fiq_write(t, 0x07, UART_SRR);
121     udelay(0x0A);
122     /* set uart to loop back mode */
123     rk_fiq_write(t, 0x10, UART_MCR);
124 
125     rk_fiq_write(t, 0x83, UART_LCR);
126     /* set baud rate */
127     rk_fiq_write(t, dll, UART_DLL);
128     rk_fiq_write(t, dlm, UART_DLM);
129     rk_fiq_write(t, 0x03, UART_LCR);
130 
131     /* enable rx interrupt */
132     rk_fiq_write(t, UART_IER_RDI, UART_IER);
133 
134     /*
135      * Interrupt on every character when received, but we can enable fifo for TX
136      * I found that if we enable the RX fifo, some problem may vanish such as when
137      * you continuously input characters in the command line the uart irq may be disable
138      * because of the uart irq is served when CPU is at IRQ exception, but it is
139      * found unregistered, so it is disable.
140      */
141     rk_fiq_write(t, 0x01, UART_FCR);
142 
143     /* disbale loop back mode */
144     rk_fiq_write(t, 0x0, UART_MCR);
145 
146     console_unlock();
147 
148     return 0;
149 }
150 
debug_getc(struct platform_device * pdev)151 static int debug_getc(struct platform_device *pdev)
152 {
153     unsigned int lsr;
154     struct rk_fiq_debugger *t;
155     unsigned int temp;
156     static unsigned int n;
157     static char buf[32];
158 
159     t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
160     /*
161      * Clear uart interrupt status
162      */
163     rk_fiq_read(t, UART_USR);
164     lsr = rk_fiq_read_lsr(t);
165     if (lsr & UART_LSR_DR) {
166         temp = rk_fiq_read(t, UART_RX);
167         buf[n & 0x1f] = temp;
168         n++;
169         if (temp == 'q' && n > 0x02) {
170             if ((buf[(n - 0x02) & 0x1f] == 'i') && (buf[(n - 0x03) & 0x1f] == 'f')) {
171                 return FIQ_DEBUGGER_BREAK;
172             } else {
173                 return temp;
174             }
175         } else {
176             return temp;
177         }
178     }
179 
180     return FIQ_DEBUGGER_NO_CHAR;
181 }
182 
debug_putc(struct platform_device * pdev,unsigned int c)183 static void debug_putc(struct platform_device *pdev, unsigned int c)
184 {
185     struct rk_fiq_debugger *t;
186     unsigned int count = 10000;
187 
188     t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
189 
190     while (!(rk_fiq_read(t, UART_USR) & UART_USR_TX_FIFO_NOT_FULL) && count--) {
191         udelay(0x0A);
192     }
193 
194     rk_fiq_write(t, c, UART_TX);
195 }
196 
debug_getc_dummy(struct platform_device * pdev)197 static int debug_getc_dummy(struct platform_device *pdev)
198 {
199     return FIQ_DEBUGGER_NO_CHAR;
200 }
201 
debug_putc_dummy(struct platform_device * pdev,unsigned int c)202 static void debug_putc_dummy(struct platform_device *pdev, unsigned int c)
203 {
204 }
205 
debug_flush(struct platform_device * pdev)206 static void debug_flush(struct platform_device *pdev)
207 {
208     struct rk_fiq_debugger *t;
209     unsigned int count = 10000;
210     t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
211 
212     while (!(rk_fiq_read_lsr(t) & UART_LSR_TEMT) && count--) {
213         udelay(0x0A);
214     }
215 }
216 
217 #ifdef CONFIG_RK_CONSOLE_THREAD
218 #define FIFO_SIZE SZ_64K
219 #define LINE_MAX 1024
220 static DEFINE_KFIFO(fifo, unsigned char, FIFO_SIZE);
221 static char console_buf[LINE_MAX];  /* avoid FRAME WARN */
222 static bool console_thread_stop;    /* write on console_write */
223 static bool console_thread_running; /* write on console_thread */
224 static unsigned int console_dropped_messages;
225 
console_putc(struct platform_device * pdev,unsigned int c)226 static void console_putc(struct platform_device *pdev, unsigned int c)
227 {
228     struct rk_fiq_debugger *t;
229     unsigned int count = 500;
230 
231     t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
232 
233     while (!(rk_fiq_read(t, UART_USR) & UART_USR_TX_FIFO_NOT_FULL) && count--) {
234         usleep_range(0XC8, 0XD2);
235     }
236 
237     rk_fiq_write(t, c, UART_TX);
238 }
239 
console_flush(struct platform_device * pdev)240 static void console_flush(struct platform_device *pdev)
241 {
242     struct rk_fiq_debugger *t;
243     unsigned int count = 500;
244 
245     t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
246 
247     while (!(rk_fiq_read_lsr(t) & UART_LSR_TEMT) && count--) {
248         usleep_range(0xC8, 0XD2);
249     }
250 }
251 
console_put(struct platform_device * pdev,const char * s,unsigned int count)252 static void console_put(struct platform_device *pdev, const char *s, unsigned int count)
253 {
254     while (count--) {
255         if (*s == '\n') {
256             console_putc(pdev, '\r');
257         }
258         console_putc(pdev, *s++);
259     }
260 }
261 
debug_put(struct platform_device * pdev,const char * s,unsigned int count)262 static void debug_put(struct platform_device *pdev, const char *s, unsigned int count)
263 {
264     while (count--) {
265         if (*s == '\n') {
266             debug_putc(pdev, '\r');
267         }
268         debug_putc(pdev, *s++);
269     }
270 }
271 
console_thread(void * data)272 static int console_thread(void *data)
273 {
274     struct platform_device *pdev = data;
275     char *buf = console_buf;
276     unsigned int len;
277 
278     while (1) {
279         unsigned int dropped;
280 
281         set_current_state(TASK_INTERRUPTIBLE);
282         if (kfifo_is_empty(&fifo)) {
283             smp_store_mb(console_thread_running, false);
284             schedule();
285             smp_store_mb(console_thread_running, true);
286         }
287         if (kthread_should_stop()) {
288             break;
289         }
290         set_current_state(TASK_RUNNING);
291         while (!console_thread_stop) {
292             len = kfifo_out(&fifo, buf, LINE_MAX);
293             if (!len) {
294                 break;
295             }
296             console_put(pdev, buf, len);
297         }
298         dropped = console_dropped_messages;
299         if (dropped && !console_thread_stop) {
300             console_dropped_messages = 0;
301             smp_wmb();
302             len = snprintf(buf, LINE_MAX, "** %u console messages dropped **\n", dropped);
303             console_put(pdev, buf, len);
304         }
305         if (!console_thread_stop) {
306             console_flush(pdev);
307         }
308     }
309 
310     return 0;
311 }
312 
console_write(struct platform_device * pdev,const char * s,unsigned int count)313 static void console_write(struct platform_device *pdev, const char *s, unsigned int count)
314 {
315     unsigned int fifo_count = FIFO_SIZE;
316     unsigned char c;
317     struct rk_fiq_debugger *t;
318 
319     t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
320 
321     if (console_thread_stop || oops_in_progress || system_state == SYSTEM_HALT || system_state == SYSTEM_POWER_OFF ||
322         system_state == SYSTEM_RESTART) {
323         if (!console_thread_stop) {
324             console_thread_stop = true;
325             smp_wmb();
326             debug_flush(pdev);
327             while (fifo_count-- && kfifo_get(&fifo, &c)) {
328                 debug_put(pdev, &c, 1);
329             }
330         }
331         debug_put(pdev, s, count);
332         debug_flush(pdev);
333     } else if (count) {
334         unsigned int ret = 0;
335 
336         if (kfifo_len(&fifo) + count < FIFO_SIZE) {
337             ret = kfifo_in(&fifo, s, count);
338         }
339         if (!ret) {
340             console_dropped_messages++;
341             smp_wmb();
342         } else {
343             /*
344              * Avoid dead lock on console_task->pi_lock and console_lock
345              * when call printk() in try_to_wake_up().
346              *
347              * cpu0 hold console_lock, then try lock pi_lock fail:
348              *   printk()->vprintk_emit()->console_unlock()->try_to_wake_up()
349              *   ->lock(pi_lock)->deadlock
350              *
351              * cpu1 hold pi_lock, then try lock console_lock fail:
352              *   console_thread()->console_put()->usleep_range()->run_hrtimer()
353              *   ->hrtimer_wakeup()->try_to_wake_up()[hold_pi_lock]->printk()
354              *   ->vprintk_emit()->console_trylock_spining()->cpu_relax()->deadlock
355              *
356              * if cpu0 does not hold console_lock, cpu1 also deadlock on pi_lock:
357              *   ...->hrtimer_wakeup()->try_to_wake_up()[hold_pi_lock]->printk()
358              *   ->vprintk_emit()->console_unlock()->try_to_wake_up()
359              *   ->lock(pi_lock)->deadlock
360              *
361              * so when console_task is running on usleep_range(), printk()
362              * should not wakeup console_task to avoid lock(pi_lock) again,
363              * as run_hrtimer() will wakeup console_task later.
364              * console_thread_running==false guarantee that console_task
365              * is not running on usleep_range().
366              */
367             if (!READ_ONCE(console_thread_running)) {
368                 wake_up_process(t->console_task);
369             }
370         }
371     }
372 }
373 #endif
374 
fiq_enable(struct platform_device * pdev,unsigned int irq,bool on)375 static void fiq_enable(struct platform_device *pdev, unsigned int irq, bool on)
376 {
377     if (on) {
378         enable_irq(irq);
379     } else {
380         disable_irq(irq);
381     }
382 }
383 
384 #ifdef CONFIG_FIQ_DEBUGGER_TRUST_ZONE
385 #ifdef CONFIG_ARM_SDE_INTERFACE
386 #include <linux/arm_sdei.h>
387 #include <asm/smp_plat.h>
388 #include <linux/suspend.h>
389 void fiq_debugger_fiq_get_(const char *fmt, ...);
390 
391 static struct rk_fiq_sdei_st {
392     u32 cur_cpu;
393     u32 sw_cpu;
394     u32 cpu_can_sw;
395     int fiq_en;
396     u32 event_id;
397     u32 cpu_off_sw;
398     u32 cpu_sw_event_id;
399 } rk_fiq_sdei;
400 
sdei_fiq_debugger_is_enabled(void)401 int sdei_fiq_debugger_is_enabled(void)
402 {
403     return rk_fiq_sdei.fiq_en;
404 }
405 
fiq_sdei_event_callback(u32 event,struct pt_regs * regs,void * arg)406 int fiq_sdei_event_callback(u32 event, struct pt_regs *regs, void *arg)
407 {
408     int cpu_id = get_logical_index(read_cpuid_mpidr() & MPIDR_HWID_BITMASK);
409     fiq_debugger_fiq(regs, cpu_id);
410 
411     return 0;
412 }
413 
rk_fiq_sdei_event_sw_cpu(int wait_disable)414 void rk_fiq_sdei_event_sw_cpu(int wait_disable)
415 {
416     unsigned long affinity;
417     int cnt = 100000;
418     int ret = 0;
419 
420     do {
421         ret = sdei_event_disable_nolock(rk_fiq_sdei.event_id);
422         if (!ret) {
423             break;
424         }
425         cnt--;
426         udelay(0x14);
427     } while (wait_disable && cnt);
428 
429     affinity = cpu_logical_map(rk_fiq_sdei.sw_cpu) & MPIDR_HWID_BITMASK;
430     ret = sdei_event_routing_set_nolock(rk_fiq_sdei.event_id, SDEI_EVENT_REGISTER_RM_PE, affinity);
431     ret = sdei_event_enable_nolock(rk_fiq_sdei.event_id);
432     rk_fiq_sdei.cur_cpu = rk_fiq_sdei.sw_cpu;
433 }
434 
fiq_sdei_sw_cpu_event_callback(u32 event,struct pt_regs * regs,void * arg)435 int fiq_sdei_sw_cpu_event_callback(u32 event, struct pt_regs *regs, void *arg)
436 {
437     int cnt = 10000;
438     int ret = 0;
439     int cpu_id = event - rk_fiq_sdei.cpu_sw_event_id;
440 
441     WARN_ON(cpu_id != get_logical_index(read_cpuid_mpidr() & MPIDR_HWID_BITMASK));
442 
443     if (cpu_id == rk_fiq_sdei.sw_cpu) {
444         if (!rk_fiq_sdei.cpu_off_sw) {
445             rk_fiq_sdei.cpu_can_sw = 1;
446         } else {
447             rk_fiq_sdei_event_sw_cpu(1);
448             rk_fiq_sdei.cpu_off_sw = 0;
449         }
450     } else if (cpu_id == rk_fiq_sdei.cur_cpu && !rk_fiq_sdei.cpu_off_sw) {
451         while (!rk_fiq_sdei.cpu_can_sw && cnt) {
452             udelay(0x0A);
453             cnt--;
454         };
455 
456         if (rk_fiq_sdei.cpu_can_sw) {
457             rk_fiq_sdei_event_sw_cpu(0);
458             rk_fiq_sdei.cpu_can_sw = 0;
459         }
460     }
461     return ret;
462 }
463 
_rk_fiq_dbg_sdei_switch_cpu(unsigned int cpu,int cpu_off)464 static void _rk_fiq_dbg_sdei_switch_cpu(unsigned int cpu, int cpu_off)
465 {
466     if (cpu == rk_fiq_sdei.cur_cpu) {
467         return;
468     }
469     rk_fiq_sdei.sw_cpu = cpu;
470     rk_fiq_sdei.cpu_can_sw = 0;
471     rk_fiq_sdei.cpu_off_sw = cpu_off;
472     sip_fiq_debugger_sdei_switch_cpu(rk_fiq_sdei.cur_cpu, cpu, cpu_off);
473 }
474 
rk_fiq_dbg_sdei_switch_cpu(struct platform_device * pdev,unsigned int cpu)475 static void rk_fiq_dbg_sdei_switch_cpu(struct platform_device *pdev, unsigned int cpu)
476 {
477     _rk_fiq_dbg_sdei_switch_cpu(cpu, 0);
478 }
479 
fiq_dbg_sdei_cpu_off_migrate_fiq(unsigned int cpu)480 static int fiq_dbg_sdei_cpu_off_migrate_fiq(unsigned int cpu)
481 {
482     unsigned int target_cpu;
483     int cnt = 10000;
484 
485     if (rk_fiq_sdei.cur_cpu == cpu) {
486         target_cpu = cpumask_first(cpu_online_mask);
487         _rk_fiq_dbg_sdei_switch_cpu(target_cpu, 1);
488 
489         while (rk_fiq_sdei.cur_cpu == cpu && cnt) {
490             udelay(0x0A);
491             cnt--;
492         };
493         if (!cnt) {
494             pr_err("%s: from %d to %d err!\n", __func__, cpu, target_cpu);
495         }
496     }
497 
498     return 0;
499 }
500 
fiq_dbg_sdei_pm_callback(struct notifier_block * nb,unsigned long mode,void * _unused)501 static int fiq_dbg_sdei_pm_callback(struct notifier_block *nb, unsigned long mode, void *_unused)
502 {
503     unsigned int target_cpu;
504 
505     switch (mode) {
506         case PM_SUSPEND_PREPARE:
507             target_cpu = cpumask_first(cpu_online_mask);
508             if (target_cpu != 0) {
509                 pr_err("%s: fiq for core !\n", __func__);
510             } else {
511                 _rk_fiq_dbg_sdei_switch_cpu(target_cpu, 1);
512             }
513             break;
514         default:
515             break;
516     }
517     return 0;
518 }
519 
520 static struct notifier_block fiq_dbg_sdei_pm_nb = {
521     .notifier_call = fiq_dbg_sdei_pm_callback,
522 };
523 
fiq_debugger_sdei_enable(struct rk_fiq_debugger * t)524 static int fiq_debugger_sdei_enable(struct rk_fiq_debugger *t)
525 {
526     int ret, cpu, i;
527 
528     ret = sip_fiq_debugger_sdei_get_event_id(&rk_fiq_sdei.event_id, &rk_fiq_sdei.cpu_sw_event_id, NULL);
529     if (ret) {
530         pr_err("%s: get event id error!\n", __func__);
531         return ret;
532     }
533 
534     ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "soc/rk_sdei_fiq_debugger", NULL,
535                                     fiq_dbg_sdei_cpu_off_migrate_fiq);
536     if (ret < 0) {
537         pr_err("%s: cpuhp_setup_state_nocalls error! %d\n", __func__, ret);
538         return ret;
539     }
540 
541     if (register_pm_notifier(&fiq_dbg_sdei_pm_nb)) {
542         pr_err("%s: register pm notify error: %d!\n", __func__, ret);
543         return ret;
544     }
545 
546     ret = sdei_event_register(rk_fiq_sdei.event_id, fiq_sdei_event_callback, NULL);
547     if (ret) {
548         pr_err("%s: sdei_event_register error!\n", __func__);
549         unregister_pm_notifier(&fiq_dbg_sdei_pm_nb);
550         return ret;
551     }
552 
553     rk_fiq_sdei.cur_cpu = 0;
554 
555     ret = sdei_event_routing_set(rk_fiq_sdei.event_id, SDEI_EVENT_REGISTER_RM_PE, cpu_logical_map(rk_fiq_sdei.cur_cpu));
556     if (ret) {
557         pr_err("%s: sdei_event_routing_set error!\n", __func__);
558         goto err;
559     }
560 
561     ret = sdei_event_enable(rk_fiq_sdei.event_id);
562     if (ret) {
563         pr_err("%s: sdei_event_enable error!\n", __func__);
564         goto err;
565     }
566 
567     for (cpu = 0; cpu < num_possible_cpus(); cpu++) {
568         ret = sdei_event_register(rk_fiq_sdei.cpu_sw_event_id + cpu, fiq_sdei_sw_cpu_event_callback, NULL);
569         if (ret) {
570             pr_err("%s: cpu %d sdei_event_register error!\n", __func__, cpu);
571             goto cpu_sw_err;
572         }
573         ret =
574             sdei_event_routing_set(rk_fiq_sdei.cpu_sw_event_id + cpu, SDEI_EVENT_REGISTER_RM_PE, cpu_logical_map(cpu));
575         if (ret) {
576             pr_err("%s:cpu %d fiq_sdei_event_routing_set error!\n", __func__, cpu);
577             goto cpu_sw_err;
578         }
579 
580         ret = sdei_event_enable(rk_fiq_sdei.cpu_sw_event_id + cpu);
581         if (ret) {
582             pr_err("%s: cpu %d sdei_event_enable error!\n", __func__, cpu);
583             goto cpu_sw_err;
584         }
585     }
586 
587     t->pdata.switch_cpu = rk_fiq_dbg_sdei_switch_cpu;
588     rk_fiq_sdei.fiq_en = 1;
589     return 0;
590 cpu_sw_err:
591     for (i = 0; i < cpu; i++) {
592         sdei_event_unregister(rk_fiq_sdei.cpu_sw_event_id + i);
593     }
594 err:
595     unregister_pm_notifier(&fiq_dbg_sdei_pm_nb);
596     sdei_event_unregister(rk_fiq_sdei.event_id);
597 
598     return ret;
599 }
600 
601 #else
fiq_debugger_sdei_enable(struct rk_fiq_debugger * t)602 static inline int fiq_debugger_sdei_enable(struct rk_fiq_debugger *t)
603 {
604     return -EINVAL;
605 }
606 #endif
607 
608 static struct pt_regs fiq_pt_regs;
609 
rk_fiq_debugger_switch_cpu(struct platform_device * pdev,unsigned int cpu)610 static void rk_fiq_debugger_switch_cpu(struct platform_device *pdev, unsigned int cpu)
611 {
612     sip_fiq_debugger_switch_cpu(cpu);
613 }
614 
rk_fiq_debugger_enable_debug(struct platform_device * pdev,bool val)615 static void rk_fiq_debugger_enable_debug(struct platform_device *pdev, bool val)
616 {
617     sip_fiq_debugger_enable_debug(val);
618 }
619 
fiq_debugger_uart_irq_tf(struct pt_regs _pt_regs,u64 cpu)620 static void fiq_debugger_uart_irq_tf(struct pt_regs _pt_regs, u64 cpu)
621 {
622     fiq_pt_regs = _pt_regs;
623 
624     fiq_debugger_fiq(&fiq_pt_regs, cpu);
625 }
626 
rk_fiq_debugger_uart_dev_resume(struct platform_device * pdev)627 static int rk_fiq_debugger_uart_dev_resume(struct platform_device *pdev)
628 {
629     struct rk_fiq_debugger *t;
630 
631     t = container_of(dev_get_platdata(&pdev->dev), typeof(*t), pdata);
632     sip_fiq_debugger_uart_irq_tf_init(serial_hwirq, fiq_debugger_uart_irq_tf);
633     return 0;
634 }
635 
636 /*
637  * We don't need to migrate fiq before cpuidle, because EL3 can promise to
638  * resume all fiq configure. We don't want fiq to break kernel cpu_resume(),
639  * so that fiq would be disabled in EL3 on purpose when cpu resume. We enable
640  * it here since everything is okay.
641  */
fiq_debugger_cpuidle_resume_fiq(struct notifier_block * nb,unsigned long action,void * hcpu)642 static int fiq_debugger_cpuidle_resume_fiq(struct notifier_block *nb, unsigned long action, void *hcpu)
643 {
644     switch (action) {
645         case CPU_PM_EXIT:
646             if ((sip_fiq_debugger_is_enabled()) && (sip_fiq_debugger_get_target_cpu() == smp_processor_id())) {
647                 sip_fiq_debugger_enable_fiq(true, smp_processor_id());
648             }
649             break;
650         default:
651             break;
652     }
653 
654     return NOTIFY_OK;
655 }
656 
657 /*
658  * We must migrate fiq before cpu offline, because EL3 doesn't promise to
659  * resume all fiq configure at this sisutation. Here, we migrate fiq to any
660  * online cpu.
661  */
fiq_debugger_cpu_offine_migrate_fiq(unsigned int cpu)662 static int fiq_debugger_cpu_offine_migrate_fiq(unsigned int cpu)
663 {
664     unsigned int target_cpu;
665 
666     if ((sip_fiq_debugger_is_enabled()) && (sip_fiq_debugger_get_target_cpu() == cpu)) {
667         target_cpu = cpumask_first(cpu_online_mask);
668         sip_fiq_debugger_switch_cpu(target_cpu);
669     }
670 
671     return 0;
672 }
673 
674 static struct notifier_block fiq_debugger_pm_notifier = {
675     .notifier_call = fiq_debugger_cpuidle_resume_fiq,
676     .priority = 100,
677 };
678 
rk_fiq_debugger_register_cpu_pm_notify(void)679 static int rk_fiq_debugger_register_cpu_pm_notify(void)
680 {
681     int err;
682 
683     err = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "soc/rk_fiq_debugger", NULL,
684                                     fiq_debugger_cpu_offine_migrate_fiq);
685     if (err < 0) {
686         pr_err("fiq debugger register cpu notifier failed!\n");
687         return err;
688     }
689 
690     err = cpu_pm_register_notifier(&fiq_debugger_pm_notifier);
691     if (err) {
692         pr_err("fiq debugger register pm notifier failed!\n");
693         return err;
694     }
695 
696     return 0;
697 }
698 
fiq_debugger_bind_sip_smc(struct rk_fiq_debugger * t,phys_addr_t phy_base,int hwirq,int signal_irq,unsigned int baudrate)699 static int fiq_debugger_bind_sip_smc(struct rk_fiq_debugger *t, phys_addr_t phy_base, int hwirq, int signal_irq,
700                                      unsigned int baudrate)
701 {
702     int err;
703 
704     err = sip_fiq_debugger_request_share_memory();
705     if (err) {
706         pr_err("fiq debugger request share memory failed: %d\n", err);
707         goto exit;
708     }
709 
710     err = rk_fiq_debugger_register_cpu_pm_notify();
711     if (err) {
712         pr_err("fiq debugger register cpu pm notify failed: %d\n", err);
713         goto exit;
714     }
715 
716     err = sip_fiq_debugger_uart_irq_tf_init(hwirq, fiq_debugger_uart_irq_tf);
717     if (err) {
718         pr_err("fiq debugger bind fiq to trustzone failed: %d\n", err);
719         goto exit;
720     }
721 
722     t->pdata.uart_dev_resume = rk_fiq_debugger_uart_dev_resume;
723     t->pdata.switch_cpu = rk_fiq_debugger_switch_cpu;
724     t->pdata.enable_debug = rk_fiq_debugger_enable_debug;
725     sip_fiq_debugger_set_print_port(phy_base, baudrate);
726 
727     pr_info("fiq debugger fiq mode enabled\n");
728 
729     return 0;
730 
731 exit:
732     t->pdata.switch_cpu = NULL;
733     t->pdata.enable_debug = NULL;
734 
735     return err;
736 }
737 #endif
738 
rk_serial_debug_init(void __iomem * base,phys_addr_t phy_base,int irq,int signal_irq,int wakeup_irq,unsigned int baudrate)739 void rk_serial_debug_init(void __iomem *base, phys_addr_t phy_base, int irq, int signal_irq, int wakeup_irq,
740                           unsigned int baudrate)
741 {
742     struct rk_fiq_debugger *t = NULL;
743     struct platform_device *pdev = NULL;
744     struct resource *res = NULL;
745     int res_count = 0;
746 #ifdef CONFIG_FIQ_DEBUGGER_TRUST_ZONE
747     int ret = 0;
748 #endif
749 
750     if (!base) {
751         pr_err("Invalid fiq debugger uart base\n");
752         return;
753     }
754 
755     t = kzalloc(sizeof(struct rk_fiq_debugger), GFP_KERNEL);
756     if (!t) {
757         pr_err("Failed to allocate for fiq debugger\n");
758         return;
759     }
760 
761     t->irq = irq;
762     t->baudrate = baudrate;
763     t->pdata.uart_init = debug_port_init;
764     t->pdata.uart_getc = debug_getc;
765     t->pdata.uart_putc = debug_putc;
766 #ifndef CONFIG_RK_CONSOLE_THREAD
767     t->pdata.uart_flush = debug_flush;
768 #endif
769     t->pdata.fiq_enable = fiq_enable;
770     t->pdata.force_irq = NULL;
771     t->debug_port_base = base;
772 
773     res = kzalloc(sizeof(struct resource) * 3, GFP_KERNEL);
774     if (!res) {
775         pr_err("Failed to alloc fiq debugger resources\n");
776         goto out2;
777     }
778 
779     pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
780     if (!pdev) {
781         pr_err("Failed to alloc fiq debugger platform device\n");
782         goto out3;
783     }
784 
785     /* clear busy interrupt, make sure all interrupts are disabled */
786     rk_fiq_read(t, UART_USR);
787 #ifdef CONFIG_FIQ_DEBUGGER_TRUST_ZONE
788     if ((signal_irq > 0) && (serial_hwirq > 0)) {
789         ret = fiq_debugger_sdei_enable(t);
790         if (ret) {
791             ret = fiq_debugger_bind_sip_smc(t, phy_base, serial_hwirq, signal_irq, baudrate);
792         }
793         if (ret) {
794             tf_fiq_sup = false;
795         } else {
796             tf_fiq_sup = true;
797         }
798     }
799 #endif
800 
801     if (irq > 0) {
802         res[0].flags = IORESOURCE_IRQ;
803         res[0].start = irq;
804         res[0].end = irq;
805 #if defined(CONFIG_FIQ_GLUE)
806         if (signal_irq > 0) {
807             res[0].name = "fiq";
808         } else {
809             res[0].name = "uart_irq";
810         }
811 #elif defined(CONFIG_FIQ_DEBUGGER_TRUST_ZONE)
812         if (tf_fiq_sup && (signal_irq > 0)) {
813             res[0].name = "fiq";
814         } else {
815             res[0].name = "uart_irq";
816         }
817 #else
818         res[0].name = "uart_irq";
819 #endif
820         res_count++;
821     }
822 
823     if (signal_irq > 0) {
824         res[1].flags = IORESOURCE_IRQ;
825         res[1].start = signal_irq;
826         res[1].end = signal_irq;
827         res[1].name = "signal";
828         res_count++;
829     }
830 
831     if (wakeup_irq > 0) {
832         res[2].flags = IORESOURCE_IRQ;
833         res[2].start = wakeup_irq;
834         res[2].end = wakeup_irq;
835         res[2].name = "wakeup";
836         res_count++;
837     }
838 
839 #ifdef CONFIG_RK_CONSOLE_THREAD
840     t->console_task = kthread_run(console_thread, pdev, "kconsole");
841     if (!IS_ERR(t->console_task)) {
842         t->pdata.console_write = console_write;
843     }
844 #endif
845 
846     pdev->name = "fiq_debugger";
847     pdev->id = rk_fiq_debugger_id++;
848     pdev->dev.platform_data = &t->pdata;
849     pdev->resource = res;
850     pdev->num_resources = res_count;
851     if (platform_device_register(pdev)) {
852         pr_err("Failed to register fiq debugger\n");
853         goto out4;
854     }
855     return;
856 
857 out4:
858     kfree(pdev);
859 out3:
860     kfree(res);
861 out2:
862     kfree(t);
863 }
864 
rk_serial_debug_init_dummy(void)865 void rk_serial_debug_init_dummy(void)
866 {
867     struct rk_fiq_debugger *t = NULL;
868     struct platform_device *pdev = NULL;
869 
870     t = kzalloc(sizeof(*t), GFP_KERNEL);
871     if (!t) {
872         pr_err("Failed to allocate for fiq debugger\n");
873         return;
874     }
875 
876     t->pdata.uart_getc = debug_getc_dummy;
877     t->pdata.uart_putc = debug_putc_dummy;
878 
879     pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
880     if (!pdev) {
881         pr_err("Failed to alloc fiq debugger platform device\n");
882         goto out2;
883     }
884 
885     pdev->name = "fiq_debugger";
886     pdev->id = rk_fiq_debugger_id++;
887     pdev->dev.platform_data = &t->pdata;
888     if (platform_device_register(pdev)) {
889         pr_err("Failed to register fiq debugger\n");
890         goto out3;
891     }
892     return;
893 
894 out3:
895     kfree(pdev);
896 out2:
897     kfree(t);
898 }
899 
900 #if defined(CONFIG_OF)
901 static const struct of_device_id rk_fiqdbg_of_match[] = {
902     {
903         .compatible = "rockchip,fiq-debugger",
904     },
905     {},
906 };
907 MODULE_DEVICE_TABLE(of, rk_fiqdbg_of_match);
908 #endif
909 
rk_fiqdbg_probe(struct platform_device * pdev)910 static int __init rk_fiqdbg_probe(struct platform_device *pdev)
911 {
912     void __iomem *base;
913     struct device_node *np = pdev->dev.of_node;
914     unsigned int id, ok = 0;
915     int irq, signal_irq = -1, wake_irq = -1;
916     unsigned int baudrate = 0, irq_mode = 0;
917     phys_addr_t phy_base = 0;
918     int serial_id;
919     struct clk *clk;
920     struct clk *pclk;
921     struct of_phandle_args oirq;
922     struct resource res;
923 
924     if (!of_device_is_available(np)) {
925         pr_err("fiq-debugger is disabled in device tree\n");
926         return -ENODEV;
927     }
928 
929     if (of_property_read_u32(np, "rockchip,serial-id", &serial_id)) {
930         return -EINVAL;
931     }
932 
933     if (serial_id == -1) {
934         rk_serial_debug_init_dummy();
935         return 0;
936     }
937 
938     if (of_property_read_u32(np, "rockchip,irq-mode-enable", &irq_mode)) {
939         irq_mode = -1;
940     }
941 
942     signal_irq = irq_of_parse_and_map(np, 0);
943     if (!signal_irq) {
944         return -EINVAL;
945     }
946 
947     if (of_property_read_u32(np, "rockchip,wake-irq", &wake_irq)) {
948         wake_irq = -1;
949     }
950 
951     if (of_property_read_u32(np, "rockchip,baudrate", &baudrate)) {
952         baudrate = -1;
953     }
954 
955     np = NULL;
956 
957     do {
958         np = of_find_node_by_name(np, "serial");
959         if (np) {
960             id = of_alias_get_id(np, "serial");
961             if (id == serial_id) {
962                 ok = 1;
963                 break;
964             }
965         }
966     } while (np);
967 
968     if (!ok) {
969         return -EINVAL;
970     }
971 
972     if (of_device_is_available(np)) {
973         pr_err("uart%d is enabled, please disable it\n", serial_id);
974         return -EINVAL;
975     }
976 
977     /* parse serial hw irq */
978     if (irq_mode != 1 && !of_irq_parse_one(np, 0, &oirq)) {
979         serial_hwirq = oirq.args[1] + 32;
980     }
981 
982     /* parse serial phy base address */
983     if (!of_address_to_resource(np, 0, &res)) {
984         phy_base = res.start;
985     }
986 
987     pclk = of_clk_get_by_name(np, "apb_pclk");
988     clk = of_clk_get_by_name(np, "baudclk");
989     if (unlikely(IS_ERR(clk)) || unlikely(IS_ERR(pclk))) {
990         pr_err("fiq-debugger get clock fail\n");
991         return -EINVAL;
992     }
993 
994     clk_prepare_enable(clk);
995     clk_prepare_enable(pclk);
996 
997     irq = irq_of_parse_and_map(np, 0);
998     if (!irq) {
999         return -EINVAL;
1000     }
1001 
1002     base = of_iomap(np, 0);
1003     if (base) {
1004         rk_serial_debug_init(base, phy_base, irq, signal_irq, wake_irq, baudrate);
1005     }
1006     return 0;
1007 }
1008 
1009 static struct platform_driver rk_fiqdbg_driver = {
1010     .driver =
1011         {
1012             .name = "rk-fiq-debugger",
1013             .of_match_table = of_match_ptr(rk_fiqdbg_of_match),
1014         },
1015 };
1016 
rk_fiqdbg_init(void)1017 static int __init rk_fiqdbg_init(void)
1018 {
1019     return platform_driver_probe(&rk_fiqdbg_driver, rk_fiqdbg_probe);
1020 }
1021 
1022 #if defined(CONFIG_FIQ_DEBUGGER_TRUST_ZONE) && defined(CONFIG_ARM_SDE_INTERFACE)
1023 fs_initcall(rk_fiqdbg_init);
1024 #else
1025 subsys_initcall(rk_fiqdbg_init); /* after of_platform_default_populate_init */
1026 #endif
1027 
rk_fiqdbg_exit(void)1028 static void __exit rk_fiqdbg_exit(void)
1029 {
1030     platform_driver_unregister(&rk_fiqdbg_driver);
1031 }
1032 module_exit(rk_fiqdbg_exit);
1033 
1034 MODULE_AUTHOR("Huibin Hong <huibin.hong@rock-chips.com>");
1035 MODULE_DESCRIPTION("Rockchip FIQ Debugger");
1036 MODULE_LICENSE("GPL");
1037 MODULE_ALIAS("platform:rk-fiq-debugger");
1038