xref: /openbmc/u-boot/drivers/serial/altera_uart.c (revision f13606b7)
1 /*
2  * (C) Copyright 2004, Psyent Corporation <www.psyent.com>
3  * Scott McNutt <smcnutt@psyent.com>
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 
8 
9 #include <common.h>
10 #include <watchdog.h>
11 #include <asm/io.h>
12 #include <linux/compiler.h>
13 #include <serial.h>
14 
15 typedef volatile struct {
16 	unsigned	rxdata;		/* Rx data reg */
17 	unsigned	txdata;		/* Tx data reg */
18 	unsigned	status;		/* Status reg */
19 	unsigned	control;	/* Control reg */
20 	unsigned	divisor;	/* Baud rate divisor reg */
21 	unsigned	endofpacket;	/* End-of-packet reg */
22 } nios_uart_t;
23 
24 /* status register */
25 #define NIOS_UART_PE		(1 << 0)	/* parity error */
26 #define NIOS_UART_FE		(1 << 1)	/* frame error */
27 #define NIOS_UART_BRK		(1 << 2)	/* break detect */
28 #define NIOS_UART_ROE		(1 << 3)	/* rx overrun */
29 #define NIOS_UART_TOE		(1 << 4)	/* tx overrun */
30 #define NIOS_UART_TMT		(1 << 5)	/* tx empty */
31 #define NIOS_UART_TRDY		(1 << 6)	/* tx ready */
32 #define NIOS_UART_RRDY		(1 << 7)	/* rx ready */
33 #define NIOS_UART_E		(1 << 8)	/* exception */
34 #define NIOS_UART_DCTS		(1 << 10)	/* cts change */
35 #define NIOS_UART_CTS		(1 << 11)	/* cts */
36 #define NIOS_UART_EOP		(1 << 12)	/* eop detected */
37 
38 /* control register */
39 #define NIOS_UART_IPE		(1 << 0)	/* parity error int ena*/
40 #define NIOS_UART_IFE		(1 << 1)	/* frame error int ena */
41 #define NIOS_UART_IBRK		(1 << 2)	/* break detect int ena */
42 #define NIOS_UART_IROE		(1 << 3)	/* rx overrun int ena */
43 #define NIOS_UART_ITOE		(1 << 4)	/* tx overrun int ena */
44 #define NIOS_UART_ITMT		(1 << 5)	/* tx empty int ena */
45 #define NIOS_UART_ITRDY		(1 << 6)	/* tx ready int ena */
46 #define NIOS_UART_IRRDY		(1 << 7)	/* rx ready int ena */
47 #define NIOS_UART_IE		(1 << 8)	/* exception int ena */
48 #define NIOS_UART_TBRK		(1 << 9)	/* transmit break */
49 #define NIOS_UART_IDCTS		(1 << 10)	/* cts change int ena */
50 #define NIOS_UART_RTS		(1 << 11)	/* rts */
51 #define NIOS_UART_IEOP		(1 << 12)	/* eop detected int ena */
52 
53 DECLARE_GLOBAL_DATA_PTR;
54 
55 /*------------------------------------------------------------------
56  * UART the serial port
57  *-----------------------------------------------------------------*/
58 
59 static nios_uart_t *uart = (nios_uart_t *) CONFIG_SYS_NIOS_CONSOLE;
60 
61 #if defined(CONFIG_SYS_NIOS_FIXEDBAUD)
62 
63 /*
64  * Everything's already setup for fixed-baud PTF
65  * assignment
66  */
67 static void altera_serial_setbrg(void)
68 {
69 }
70 
71 static int altera_serial_init(void)
72 {
73 	return 0;
74 }
75 
76 #else
77 
78 static void altera_serial_setbrg(void)
79 {
80 	unsigned div;
81 
82 	div = (CONFIG_SYS_CLK_FREQ/gd->baudrate)-1;
83 	writel (div, &uart->divisor);
84 }
85 
86 static int altera_serial_init(void)
87 {
88 	serial_setbrg();
89 	return 0;
90 }
91 
92 #endif /* CONFIG_SYS_NIOS_FIXEDBAUD */
93 
94 /*-----------------------------------------------------------------------
95  * UART CONSOLE
96  *---------------------------------------------------------------------*/
97 static void altera_serial_putc(char c)
98 {
99 	if (c == '\n')
100 		serial_putc ('\r');
101 	while ((readl (&uart->status) & NIOS_UART_TRDY) == 0)
102 		WATCHDOG_RESET ();
103 	writel ((unsigned char)c, &uart->txdata);
104 }
105 
106 static int altera_serial_tstc(void)
107 {
108 	return (readl (&uart->status) & NIOS_UART_RRDY);
109 }
110 
111 static int altera_serial_getc(void)
112 {
113 	while (serial_tstc () == 0)
114 		WATCHDOG_RESET ();
115 	return (readl (&uart->rxdata) & 0x00ff );
116 }
117 
118 static struct serial_device altera_serial_drv = {
119 	.name	= "altera_serial",
120 	.start	= altera_serial_init,
121 	.stop	= NULL,
122 	.setbrg	= altera_serial_setbrg,
123 	.putc	= altera_serial_putc,
124 	.puts	= default_serial_puts,
125 	.getc	= altera_serial_getc,
126 	.tstc	= altera_serial_tstc,
127 };
128 
129 void altera_serial_initialize(void)
130 {
131 	serial_register(&altera_serial_drv);
132 }
133 
134 __weak struct serial_device *default_serial_console(void)
135 {
136 	return &altera_serial_drv;
137 }
138