1/*
2 *  Copyright (C) 2008-2010 Thomas Chou <thomas@wytron.com.tw>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 *
17 */
18
19#include <linux/io.h>
20
21#if (defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE) && defined(JTAG_UART_BASE))\
22	|| (defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE) && defined(UART0_BASE))
23static void *my_ioremap(unsigned long physaddr)
24{
25	return (void *)(physaddr | CONFIG_NIOS2_IO_REGION_BASE);
26}
27#endif
28
29#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE) && defined(JTAG_UART_BASE)
30
31#define ALTERA_JTAGUART_SIZE				8
32#define ALTERA_JTAGUART_DATA_REG			0
33#define ALTERA_JTAGUART_CONTROL_REG			4
34#define ALTERA_JTAGUART_CONTROL_AC_MSK			(0x00000400)
35#define ALTERA_JTAGUART_CONTROL_WSPACE_MSK		(0xFFFF0000)
36static void *uartbase;
37
38#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS)
39static void jtag_putc(int ch)
40{
41	if (readl(uartbase + ALTERA_JTAGUART_CONTROL_REG) &
42		ALTERA_JTAGUART_CONTROL_WSPACE_MSK)
43		writeb(ch, uartbase + ALTERA_JTAGUART_DATA_REG);
44}
45#else
46static void jtag_putc(int ch)
47{
48	while ((readl(uartbase + ALTERA_JTAGUART_CONTROL_REG) &
49		ALTERA_JTAGUART_CONTROL_WSPACE_MSK) == 0)
50		;
51	writeb(ch, uartbase + ALTERA_JTAGUART_DATA_REG);
52}
53#endif
54
55static int putchar(int ch)
56{
57	jtag_putc(ch);
58	return ch;
59}
60
61static void console_init(void)
62{
63	uartbase = my_ioremap((unsigned long) JTAG_UART_BASE);
64	writel(ALTERA_JTAGUART_CONTROL_AC_MSK,
65		uartbase + ALTERA_JTAGUART_CONTROL_REG);
66}
67
68#elif defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE) && defined(UART0_BASE)
69
70#define ALTERA_UART_SIZE		32
71#define ALTERA_UART_TXDATA_REG		4
72#define ALTERA_UART_STATUS_REG		8
73#define ALTERA_UART_DIVISOR_REG		16
74#define ALTERA_UART_STATUS_TRDY_MSK	(0x40)
75static unsigned uartbase;
76
77static void uart_putc(int ch)
78{
79	int i;
80
81	for (i = 0; (i < 0x10000); i++) {
82		if (readw(uartbase + ALTERA_UART_STATUS_REG) &
83			ALTERA_UART_STATUS_TRDY_MSK)
84			break;
85	}
86	writeb(ch, uartbase + ALTERA_UART_TXDATA_REG);
87}
88
89static int putchar(int ch)
90{
91	uart_putc(ch);
92	if (ch == '\n')
93		uart_putc('\r');
94	return ch;
95}
96
97static void console_init(void)
98{
99	unsigned int baud, baudclk;
100
101	uartbase = (unsigned long) my_ioremap((unsigned long) UART0_BASE);
102	baud = CONFIG_SERIAL_ALTERA_UART_BAUDRATE;
103	baudclk = UART0_FREQ / baud;
104	writew(baudclk, uartbase + ALTERA_UART_DIVISOR_REG);
105}
106
107#else
108
109static int putchar(int ch)
110{
111	return ch;
112}
113
114static void console_init(void)
115{
116}
117
118#endif
119
120static int puts(const char *s)
121{
122	while (*s)
123		putchar(*s++);
124	return 0;
125}
126