]> git.karo-electronics.de Git - karo-tx-linux.git/blob - arch/mips/mti-sead3/sead3-init.c
MIPS: SEAD3: Probe UARTs using DT
[karo-tx-linux.git] / arch / mips / mti-sead3 / sead3-init.c
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
7  */
8 #include <linux/init.h>
9 #include <linux/io.h>
10
11 #include <asm/bootinfo.h>
12 #include <asm/cacheflush.h>
13 #include <asm/traps.h>
14 #include <asm/mips-boards/generic.h>
15 #include <asm/fw/fw.h>
16
17 extern char except_vec_nmi;
18 extern char except_vec_ejtag_debug;
19
20 static void __init mips_nmi_setup(void)
21 {
22         void *base;
23
24         base = cpu_has_veic ?
25                 (void *)(CAC_BASE + 0xa80) :
26                 (void *)(CAC_BASE + 0x380);
27 #ifdef CONFIG_CPU_MICROMIPS
28         /*
29          * Decrement the exception vector address by one for microMIPS.
30          */
31         memcpy(base, (&except_vec_nmi - 1), 0x80);
32
33         /*
34          * This is a hack. We do not know if the boot loader was built with
35          * microMIPS instructions or not. If it was not, the NMI exception
36          * code at 0x80000a80 will be taken in MIPS32 mode. The hand coded
37          * assembly below forces us into microMIPS mode if we are a pure
38          * microMIPS kernel. The assembly instructions are:
39          *
40          *  3C1A8000   lui       k0,0x8000
41          *  375A0381   ori       k0,k0,0x381
42          *  03400008   jr        k0
43          *  00000000   nop
44          *
45          * The mode switch occurs by jumping to the unaligned exception
46          * vector address at 0x80000381 which would have been 0x80000380
47          * in MIPS32 mode. The jump to the unaligned address transitions
48          * us into microMIPS mode.
49          */
50         if (!cpu_has_veic) {
51                 void *base2 = (void *)(CAC_BASE + 0xa80);
52                 *((unsigned int *)base2) = 0x3c1a8000;
53                 *((unsigned int *)base2 + 1) = 0x375a0381;
54                 *((unsigned int *)base2 + 2) = 0x03400008;
55                 *((unsigned int *)base2 + 3) = 0x00000000;
56                 flush_icache_range((unsigned long)base2,
57                         (unsigned long)base2 + 0x10);
58         }
59 #else
60         memcpy(base, &except_vec_nmi, 0x80);
61 #endif
62         flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
63 }
64
65 static void __init mips_ejtag_setup(void)
66 {
67         void *base;
68
69         base = cpu_has_veic ?
70                 (void *)(CAC_BASE + 0xa00) :
71                 (void *)(CAC_BASE + 0x300);
72 #ifdef CONFIG_CPU_MICROMIPS
73         /* Deja vu... */
74         memcpy(base, (&except_vec_ejtag_debug - 1), 0x80);
75         if (!cpu_has_veic) {
76                 void *base2 = (void *)(CAC_BASE + 0xa00);
77                 *((unsigned int *)base2) = 0x3c1a8000;
78                 *((unsigned int *)base2 + 1) = 0x375a0301;
79                 *((unsigned int *)base2 + 2) = 0x03400008;
80                 *((unsigned int *)base2 + 3) = 0x00000000;
81                 flush_icache_range((unsigned long)base2,
82                         (unsigned long)base2 + 0x10);
83         }
84 #else
85         memcpy(base, &except_vec_ejtag_debug, 0x80);
86 #endif
87         flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
88 }
89
90 void __init prom_init(void)
91 {
92         board_nmi_handler_setup = mips_nmi_setup;
93         board_ejtag_handler_setup = mips_ejtag_setup;
94
95         fw_init_cmdline();
96 #ifdef CONFIG_EARLY_PRINTK
97         if ((strstr(fw_getcmdline(), "console=ttyS0")) != NULL)
98                 fw_init_early_console(0);
99         else if ((strstr(fw_getcmdline(), "console=ttyS1")) != NULL)
100                 fw_init_early_console(1);
101 #endif
102 }
103
104 void __init prom_free_prom_memory(void)
105 {
106 }