1
2
3
4
5
6
7
8
9
10
11#include <common.h>
12#include <watchdog.h>
13#include <asm/io.h>
14#include <serial.h>
15
16DECLARE_GLOBAL_DATA_PTR;
17
18
19
20
21
22#define YANU_MAX_PRESCALER_N ((1 << 4) - 1)
23#define YANU_MAX_PRESCALER_M ((1 << 11) -1)
24#define YANU_FIFO_SIZE (16)
25#define YANU_RXFIFO_SIZE (YANU_FIFO_SIZE)
26#define YANU_TXFIFO_SIZE (YANU_FIFO_SIZE)
27
28#define YANU_RXFIFO_DLY (10*11)
29#define YANU_TXFIFO_THR (10)
30#define YANU_DATA_CHAR_MASK (0xFF)
31
32
33#define YANU_DATA_OFFSET (0)
34
35#define YANU_CONTROL_OFFSET (4)
36
37#define YANU_CONTROL_IE_RRDY (1<<0)
38#define YANU_CONTROL_IE_OE (1<<1)
39#define YANU_CONTROL_IE_BRK (1<<2)
40#define YANU_CONTROL_IE_FE (1<<3)
41#define YANU_CONTROL_IE_PE (1<<4)
42#define YANU_CONTROL_IE_TRDY (1<<5)
43
44#define YANU_CONTROL_BITS_POS (6)
45#define YANU_CONTROL_BITS (1<<YANU_CONTROL_BITS_POS)
46#define YANU_CONTROL_BITS_N (3)
47#define YANU_CONTROL_PARENA (1<<9)
48#define YANU_CONTROL_PAREVEN (1<<10)
49#define YANU_CONTROL_STOPS (1<<11)
50#define YANU_CONTROL_HHENA (1<<12)
51#define YANU_CONTROL_FORCEBRK (1<<13)
52
53#define YANU_CONTROL_RDYDLY (1<<14)
54#define YANU_CONTROL_RDYDLY_N (8)
55#define YANU_CONTROL_TXTHR (1<<22)
56#define YANU_CONTROL_TXTHR_N (4)
57
58#define YANU_BAUD_OFFSET (8)
59#define YANU_BAUDM (1<<0)
60#define YANU_BAUDM_N (12)
61#define YANU_BAUDE (1<<12)
62#define YANU_BAUDE_N (4)
63
64#define YANU_ACTION_OFFSET (12)
65#define YANU_ACTION_RRRDY (1<<0)
66#define YANU_ACTION_ROE (1<<1)
67#define YANU_ACTION_RBRK (1<<2)
68#define YANU_ACTION_RFE (1<<3)
69#define YANU_ACTION_RPE (1<<4)
70#define YANU_ACTION_SRRDY (1<<5)
71#define YANU_ACTION_SOE (1<<6)
72#define YANU_ACTION_SBRK (1<<7)
73#define YANU_ACTION_SFE (1<<8)
74#define YANU_ACTION_SPE (1<<9)
75#define YANU_ACTION_RFIFO_PULL (1<<10)
76#define YANU_ACTION_RFIFO_CLEAR (1<<11)
77#define YANU_ACTION_TFIFO_CLEAR (1<<12)
78#define YANU_ACTION_RTRDY (1<<13)
79#define YANU_ACTION_STRDY (1<<14)
80
81#define YANU_STATUS_OFFSET (16)
82#define YANU_STATUS_RRDY (1<<0)
83#define YANU_STATUS_TRDY (1<<1)
84#define YANU_STATUS_OE (1<<2)
85#define YANU_STATUS_BRK (1<<3)
86#define YANU_STATUS_FE (1<<4)
87#define YANU_STATUS_PE (1<<5)
88#define YANU_RFIFO_CHARS_POS (6)
89#define YANU_RFIFO_CHARS (1<<RFIFO_CHAR_POS)
90#define YANU_RFIFO_CHARS_N (5)
91#define YANU_TFIFO_CHARS_POS (11)
92#define YANU_TFIFO_CHARS (1<<TFIFO_CHAR_POS)
93#define YANU_TFIFO_CHARS_N (5)
94
95typedef volatile struct {
96 volatile unsigned data;
97 volatile unsigned control;
98 volatile unsigned baud;
99 volatile unsigned action;
100 volatile unsigned status;
101 volatile unsigned magic;
102} yanu_uart_t;
103
104static yanu_uart_t *uart = (yanu_uart_t *)CONFIG_SYS_NIOS_CONSOLE;
105
106static void oc_serial_setbrg(void)
107{
108 int n, k;
109 const unsigned max_uns = 0xFFFFFFFF;
110 unsigned best_n, best_m, baud;
111 unsigned baudrate;
112
113#if defined(CONFIG_SYS_NIOS_FIXEDBAUD)
114
115 baudrate = CONFIG_BAUDRATE;
116#else
117 baudrate = gd->baudrate;
118#endif
119
120 best_n = YANU_MAX_PRESCALER_N;
121 for (n = YANU_MAX_PRESCALER_N; n >= 0; n--) {
122 if ((unsigned)CONFIG_SYS_CLK_FREQ / (1 << (n + 4)) >=
123 baudrate) {
124 best_n = n;
125 break;
126 }
127 }
128 for (k = 0;; k++) {
129 if (baudrate <= (max_uns >> (15+n-k)))
130 break;
131 }
132 best_m =
133 (baudrate * (1 << (15 + n - k))) /
134 ((unsigned)CONFIG_SYS_CLK_FREQ >> k);
135
136 baud = best_m + best_n * YANU_BAUDE;
137 writel(baud, &uart->baud);
138
139 return;
140}
141
142static int oc_serial_init(void)
143{
144 unsigned action,control;
145
146
147 action = YANU_ACTION_RRRDY |
148 YANU_ACTION_RTRDY |
149 YANU_ACTION_ROE |
150 YANU_ACTION_RBRK |
151 YANU_ACTION_RFE |
152 YANU_ACTION_RPE |
153 YANU_ACTION_RFE | YANU_ACTION_RFIFO_CLEAR | YANU_ACTION_TFIFO_CLEAR;
154
155 writel(action, &uart->action);
156
157
158
159
160
161
162
163
164 control = (0x7 << YANU_CONTROL_BITS_POS);
165
166 control |= YANU_CONTROL_PAREVEN;
167
168 control |= YANU_CONTROL_RDYDLY * YANU_RXFIFO_DLY;
169 control |= YANU_CONTROL_TXTHR * YANU_TXFIFO_THR;
170
171 writel(control, &uart->control);
172
173
174 serial_setbrg();
175
176 return (0);
177}
178
179
180
181
182
183static void oc_serial_putc(char c)
184{
185 int tx_chars;
186 unsigned status;
187
188 if (c == '\n')
189 serial_putc ('\r');
190
191 while (1) {
192 status = readl(&uart->status);
193 tx_chars = (status>>YANU_TFIFO_CHARS_POS)
194 & ((1<<YANU_TFIFO_CHARS_N)-1);
195 if (tx_chars < YANU_TXFIFO_SIZE-1)
196 break;
197 WATCHDOG_RESET ();
198 }
199
200 writel((unsigned char)c, &uart->data);
201}
202
203static int oc_serial_tstc(void)
204{
205 unsigned status ;
206
207 status = readl(&uart->status);
208 return (((status >> YANU_RFIFO_CHARS_POS) &
209 ((1 << YANU_RFIFO_CHARS_N) - 1)) > 0);
210}
211
212static int oc_serial_getc(void)
213{
214 while (serial_tstc() == 0)
215 WATCHDOG_RESET ();
216
217
218 writel(YANU_ACTION_RFIFO_PULL, &uart->action);
219
220 return(readl(&uart->data) & YANU_DATA_CHAR_MASK);
221}
222
223static struct serial_device oc_serial_drv = {
224 .name = "oc_serial",
225 .start = oc_serial_init,
226 .stop = NULL,
227 .setbrg = oc_serial_setbrg,
228 .putc = oc_serial_putc,
229 .puts = default_serial_puts,
230 .getc = oc_serial_getc,
231 .tstc = oc_serial_tstc,
232};
233
234void oc_serial_initialize(void)
235{
236 serial_register(&oc_serial_drv);
237}
238
239__weak struct serial_device *default_serial_console(void)
240{
241 return &oc_serial_drv;
242}
243