aboutsummaryrefslogtreecommitdiffstats
path: root/arch
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
parent96f3a5cc33baede169e0d330119090789e97e86b (diff)
nios2: add early printk support
Signed-off-by: Ley Foon Tan <lftan@altera.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/nios2/Kconfig.debug11
-rw-r--r--arch/nios2/include/asm/prom.h22
-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
6 files changed, 207 insertions, 1 deletions
diff --git a/arch/nios2/Kconfig.debug b/arch/nios2/Kconfig.debug
index 8d4e6bacd997..2fd08cbfdddb 100644
--- a/arch/nios2/Kconfig.debug
+++ b/arch/nios2/Kconfig.debug
@@ -14,4 +14,15 @@ config DEBUG_STACK_USAGE
14 14
15 This option will slow down process creation somewhat. 15 This option will slow down process creation somewhat.
16 16
17config EARLY_PRINTK
18 bool "Activate early kernel debugging"
19 default y
20 select SERIAL_CORE_CONSOLE
21 depends on SERIAL_ALTERA_JTAGUART_CONSOLE || SERIAL_ALTERA_UART_CONSOLE
22 help
23 Enable early printk on console
24 This is useful for kernel debugging when your machine crashes very
25 early before the console code is initialized.
26 You should normally say N here, unless you want to debug such a crash.
27
17endmenu 28endmenu
diff --git a/arch/nios2/include/asm/prom.h b/arch/nios2/include/asm/prom.h
new file mode 100644
index 000000000000..75fffb42cfa5
--- /dev/null
+++ b/arch/nios2/include/asm/prom.h
@@ -0,0 +1,22 @@
1/*
2 * Copyright Altera Corporation (C) <2015>. All rights reserved
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef __ASM_NIOS2_PROM_H__
18#define __ASM_NIOS2_PROM_H__
19
20extern unsigned long __init of_early_console(void);
21
22#endif
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