diff options
author | Ley Foon Tan <lftan@altera.com> | 2015-02-10 10:21:08 -0500 |
---|---|---|
committer | Ley Foon Tan <lftan@altera.com> | 2015-02-10 10:21:08 -0500 |
commit | e8bf5bc776edef44777b13b2eb4461d653519bae (patch) | |
tree | 91626d85686ba2938f0c1fa76633b790a76c3cfc /arch/nios2/kernel | |
parent | 96f3a5cc33baede169e0d330119090789e97e86b (diff) |
nios2: add early printk support
Signed-off-by: Ley Foon Tan <lftan@altera.com>
Diffstat (limited to 'arch/nios2/kernel')
-rw-r--r-- | arch/nios2/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/nios2/kernel/early_printk.c | 118 | ||||
-rw-r--r-- | arch/nios2/kernel/prom.c | 52 | ||||
-rw-r--r-- | arch/nios2/kernel/setup.c | 4 |
4 files changed, 174 insertions, 1 deletions
diff --git a/arch/nios2/kernel/Makefile b/arch/nios2/kernel/Makefile index 8ae76823ff93..eaaa894c432f 100644 --- a/arch/nios2/kernel/Makefile +++ b/arch/nios2/kernel/Makefile | |||
@@ -20,5 +20,6 @@ obj-y += syscall_table.o | |||
20 | obj-y += time.o | 20 | obj-y += time.o |
21 | obj-y += traps.o | 21 | obj-y += traps.o |
22 | 22 | ||
23 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | ||
23 | obj-$(CONFIG_MODULES) += module.o | 24 | obj-$(CONFIG_MODULES) += module.o |
24 | obj-$(CONFIG_NIOS2_ALIGNMENT_TRAP) += misaligned.o | 25 | obj-$(CONFIG_NIOS2_ALIGNMENT_TRAP) += misaligned.o |
diff --git a/arch/nios2/kernel/early_printk.c b/arch/nios2/kernel/early_printk.c new file mode 100644 index 000000000000..c08e4c1486fc --- /dev/null +++ b/arch/nios2/kernel/early_printk.c | |||
@@ -0,0 +1,118 @@ | |||
1 | /* | ||
2 | * Early printk for Nios2. | ||
3 | * | ||
4 | * Copyright (C) 2015, Altera Corporation | ||
5 | * Copyright (C) 2010, Tobias Klauser <tklauser@distanz.ch> | ||
6 | * Copyright (C) 2009, Wind River Systems Inc | ||
7 | * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com | ||
8 | * | ||
9 | * This file is subject to the terms and conditions of the GNU General Public | ||
10 | * License. See the file "COPYING" in the main directory of this archive | ||
11 | * for more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/console.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/io.h> | ||
18 | |||
19 | #include <asm/prom.h> | ||
20 | |||
21 | static unsigned long base_addr; | ||
22 | |||
23 | #if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE) | ||
24 | |||
25 | #define ALTERA_JTAGUART_DATA_REG 0 | ||
26 | #define ALTERA_JTAGUART_CONTROL_REG 4 | ||
27 | #define ALTERA_JTAGUART_CONTROL_WSPACE_MSK 0xFFFF0000 | ||
28 | #define ALTERA_JTAGUART_CONTROL_AC_MSK 0x00000400 | ||
29 | |||
30 | #define JUART_GET_CR() \ | ||
31 | __builtin_ldwio((void *)(base_addr + ALTERA_JTAGUART_CONTROL_REG)) | ||
32 | #define JUART_SET_CR(v) \ | ||
33 | __builtin_stwio((void *)(base_addr + ALTERA_JTAGUART_CONTROL_REG), v) | ||
34 | #define JUART_SET_TX(v) \ | ||
35 | __builtin_stwio((void *)(base_addr + ALTERA_JTAGUART_DATA_REG), v) | ||
36 | |||
37 | static void early_console_write(struct console *con, const char *s, unsigned n) | ||
38 | { | ||
39 | unsigned long status; | ||
40 | |||
41 | while (n-- && *s) { | ||
42 | while (((status = JUART_GET_CR()) | ||
43 | & ALTERA_JTAGUART_CONTROL_WSPACE_MSK) == 0) { | ||
44 | #if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS) | ||
45 | if ((status & ALTERA_JTAGUART_CONTROL_AC_MSK) == 0) | ||
46 | return; /* no connection activity */ | ||
47 | #endif | ||
48 | } | ||
49 | JUART_SET_TX(*s); | ||
50 | s++; | ||
51 | } | ||
52 | } | ||
53 | |||
54 | #elif defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE) | ||
55 | |||
56 | #define ALTERA_UART_TXDATA_REG 4 | ||
57 | #define ALTERA_UART_STATUS_REG 8 | ||
58 | #define ALTERA_UART_STATUS_TRDY 0x0040 | ||
59 | |||
60 | #define UART_GET_SR() \ | ||
61 | __builtin_ldwio((void *)(base_addr + ALTERA_UART_STATUS_REG)) | ||
62 | #define UART_SET_TX(v) \ | ||
63 | __builtin_stwio((void *)(base_addr + ALTERA_UART_TXDATA_REG), v) | ||
64 | |||
65 | static void early_console_putc(char c) | ||
66 | { | ||
67 | while (!(UART_GET_SR() & ALTERA_UART_STATUS_TRDY)) | ||
68 | ; | ||
69 | |||
70 | UART_SET_TX(c); | ||
71 | } | ||
72 | |||
73 | static void early_console_write(struct console *con, const char *s, unsigned n) | ||
74 | { | ||
75 | while (n-- && *s) { | ||
76 | early_console_putc(*s); | ||
77 | if (*s == '\n') | ||
78 | early_console_putc('\r'); | ||
79 | s++; | ||
80 | } | ||
81 | } | ||
82 | |||
83 | #else | ||
84 | # error Neither SERIAL_ALTERA_JTAGUART_CONSOLE nor SERIAL_ALTERA_UART_CONSOLE \ | ||
85 | selected | ||
86 | #endif | ||
87 | |||
88 | static struct console early_console_prom = { | ||
89 | .name = "early", | ||
90 | .write = early_console_write, | ||
91 | .flags = CON_PRINTBUFFER | CON_BOOT, | ||
92 | .index = -1 | ||
93 | }; | ||
94 | |||
95 | void __init setup_early_printk(void) | ||
96 | { | ||
97 | #if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE) || \ | ||
98 | defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE) | ||
99 | base_addr = of_early_console(); | ||
100 | #else | ||
101 | base_addr = 0; | ||
102 | #endif | ||
103 | |||
104 | if (!base_addr) | ||
105 | return; | ||
106 | |||
107 | #if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS) | ||
108 | /* Clear activity bit so BYPASS doesn't stall if we've used JTAG for | ||
109 | * downloading the kernel. This might cause early data to be lost even | ||
110 | * if the JTAG terminal is running. | ||
111 | */ | ||
112 | JUART_SET_CR(JUART_GET_CR() | ALTERA_JTAGUART_CONTROL_AC_MSK); | ||
113 | #endif | ||
114 | |||
115 | early_console = &early_console_prom; | ||
116 | register_console(early_console); | ||
117 | pr_info("early_console initialized at 0x%08lx\n", base_addr); | ||
118 | } | ||
diff --git a/arch/nios2/kernel/prom.c b/arch/nios2/kernel/prom.c index 0522d3378e3f..718dd197909f 100644 --- a/arch/nios2/kernel/prom.c +++ b/arch/nios2/kernel/prom.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Device tree support | 2 | * Device tree support |
3 | * | 3 | * |
4 | * Copyright (C) 2013 Altera Corporation | 4 | * Copyright (C) 2013, 2015 Altera Corporation |
5 | * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw> | 5 | * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw> |
6 | * | 6 | * |
7 | * Based on MIPS support for CONFIG_OF device tree support | 7 | * Based on MIPS support for CONFIG_OF device tree support |
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/of_fdt.h> | 30 | #include <linux/of_fdt.h> |
31 | #include <linux/io.h> | 31 | #include <linux/io.h> |
32 | 32 | ||
33 | #include <asm/prom.h> | ||
33 | #include <asm/sections.h> | 34 | #include <asm/sections.h> |
34 | 35 | ||
35 | void __init early_init_dt_add_memory_arch(u64 base, u64 size) | 36 | void __init early_init_dt_add_memory_arch(u64 base, u64 size) |
@@ -63,3 +64,52 @@ void __init early_init_devtree(void *params) | |||
63 | 64 | ||
64 | early_init_dt_scan(params); | 65 | early_init_dt_scan(params); |
65 | } | 66 | } |
67 | |||
68 | #ifdef CONFIG_EARLY_PRINTK | ||
69 | static int __init early_init_dt_scan_serial(unsigned long node, | ||
70 | const char *uname, int depth, void *data) | ||
71 | { | ||
72 | u64 *addr64 = (u64 *) data; | ||
73 | const char *p; | ||
74 | |||
75 | /* only consider serial nodes */ | ||
76 | if (strncmp(uname, "serial", 6) != 0) | ||
77 | return 0; | ||
78 | |||
79 | p = of_get_flat_dt_prop(node, "compatible", NULL); | ||
80 | if (!p) | ||
81 | return 0; | ||
82 | |||
83 | /* | ||
84 | * We found an altera_jtaguart but it wasn't configured for console, so | ||
85 | * skip it. | ||
86 | */ | ||
87 | #ifndef CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE | ||
88 | if (strncmp(p, "altr,juart", 10) == 0) | ||
89 | return 0; | ||
90 | #endif | ||
91 | |||
92 | /* | ||
93 | * Same for altera_uart. | ||
94 | */ | ||
95 | #ifndef CONFIG_SERIAL_ALTERA_UART_CONSOLE | ||
96 | if (strncmp(p, "altr,uart", 9) == 0) | ||
97 | return 0; | ||
98 | #endif | ||
99 | |||
100 | *addr64 = fdt_translate_address((const void *)initial_boot_params, | ||
101 | node); | ||
102 | |||
103 | return *addr64 == OF_BAD_ADDR ? 0 : 1; | ||
104 | } | ||
105 | |||
106 | unsigned long __init of_early_console(void) | ||
107 | { | ||
108 | u64 base = 0; | ||
109 | |||
110 | if (of_scan_flat_dt(early_init_dt_scan_serial, &base)) | ||
111 | return (u32)ioremap(base, 32); | ||
112 | else | ||
113 | return 0; | ||
114 | } | ||
115 | #endif /* CONFIG_EARLY_PRINTK */ | ||
diff --git a/arch/nios2/kernel/setup.c b/arch/nios2/kernel/setup.c index cb3121f975d4..b101a43d3c5a 100644 --- a/arch/nios2/kernel/setup.c +++ b/arch/nios2/kernel/setup.c | |||
@@ -139,6 +139,10 @@ void __init setup_arch(char **cmdline_p) | |||
139 | 139 | ||
140 | console_verbose(); | 140 | console_verbose(); |
141 | 141 | ||
142 | #ifdef CONFIG_EARLY_PRINTK | ||
143 | setup_early_printk(); | ||
144 | #endif | ||
145 | |||
142 | memory_start = PAGE_ALIGN((unsigned long)__pa(_end)); | 146 | memory_start = PAGE_ALIGN((unsigned long)__pa(_end)); |
143 | memory_end = (unsigned long) CONFIG_NIOS2_MEM_BASE + memory_size; | 147 | memory_end = (unsigned long) CONFIG_NIOS2_MEM_BASE + memory_size; |
144 | 148 | ||