aboutsummaryrefslogtreecommitdiffstats
path: root/arch/nios2/kernel
diff options
context:
space:
mode:
authorLey Foon Tan <lftan@altera.com>2015-02-10 10:21:08 -0500
committerLey Foon Tan <lftan@altera.com>2015-02-10 10:21:08 -0500
commite8bf5bc776edef44777b13b2eb4461d653519bae (patch)
tree91626d85686ba2938f0c1fa76633b790a76c3cfc /arch/nios2/kernel
parent96f3a5cc33baede169e0d330119090789e97e86b (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/Makefile1
-rw-r--r--arch/nios2/kernel/early_printk.c118
-rw-r--r--arch/nios2/kernel/prom.c52
-rw-r--r--arch/nios2/kernel/setup.c4
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
20obj-y += time.o 20obj-y += time.o
21obj-y += traps.o 21obj-y += traps.o
22 22
23obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
23obj-$(CONFIG_MODULES) += module.o 24obj-$(CONFIG_MODULES) += module.o
24obj-$(CONFIG_NIOS2_ALIGNMENT_TRAP) += misaligned.o 25obj-$(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
21static 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
37static 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
65static 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
73static 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 \
85selected
86#endif
87
88static struct console early_console_prom = {
89 .name = "early",
90 .write = early_console_write,
91 .flags = CON_PRINTBUFFER | CON_BOOT,
92 .index = -1
93};
94
95void __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
35void __init early_init_dt_add_memory_arch(u64 base, u64 size) 36void __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
69static 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
106unsigned 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