serial: lpuart: Prepare the driver for DM conversion
[oweals/u-boot.git] / drivers / serial / serial_lpuart.c
1 /*
2  * Copyright 2013 Freescale Semiconductor, Inc.
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include <common.h>
8 #include <watchdog.h>
9 #include <asm/io.h>
10 #include <serial.h>
11 #include <linux/compiler.h>
12 #include <asm/arch/imx-regs.h>
13 #include <asm/arch/clock.h>
14
15 #define US1_TDRE        (1 << 7)
16 #define US1_RDRF        (1 << 5)
17 #define US1_OR          (1 << 3)
18 #define UC2_TE          (1 << 3)
19 #define UC2_RE          (1 << 2)
20 #define CFIFO_TXFLUSH   (1 << 7)
21 #define CFIFO_RXFLUSH   (1 << 6)
22 #define SFIFO_RXOF      (1 << 2)
23 #define SFIFO_RXUF      (1 << 0)
24
25 #define STAT_LBKDIF     (1 << 31)
26 #define STAT_RXEDGIF    (1 << 30)
27 #define STAT_TDRE       (1 << 23)
28 #define STAT_RDRF       (1 << 21)
29 #define STAT_IDLE       (1 << 20)
30 #define STAT_OR         (1 << 19)
31 #define STAT_NF         (1 << 18)
32 #define STAT_FE         (1 << 17)
33 #define STAT_PF         (1 << 16)
34 #define STAT_MA1F       (1 << 15)
35 #define STAT_MA2F       (1 << 14)
36 #define STAT_FLAGS      (STAT_LBKDIF | STAT_RXEDGIF | STAT_IDLE | STAT_OR | \
37                          STAT_NF | STAT_FE | STAT_PF | STAT_MA1F | STAT_MA2F)
38
39 #define CTRL_TE         (1 << 19)
40 #define CTRL_RE         (1 << 18)
41
42 #define FIFO_TXFE               0x80
43 #define FIFO_RXFE               0x40
44
45 #define WATER_TXWATER_OFF       1
46 #define WATER_RXWATER_OFF       16
47
48 DECLARE_GLOBAL_DATA_PTR;
49
50 struct lpuart_fsl *base = (struct lpuart_fsl *)LPUART_BASE;
51
52 #ifndef CONFIG_LPUART_32B_REG
53 static void _lpuart_serial_setbrg(struct lpuart_fsl *base, int baudrate)
54 {
55         u32 clk = mxc_get_clock(MXC_UART_CLK);
56         u16 sbr;
57
58         sbr = (u16)(clk / (16 * baudrate));
59
60         /* place adjustment later - n/32 BRFA */
61         __raw_writeb(sbr >> 8, &base->ubdh);
62         __raw_writeb(sbr & 0xff, &base->ubdl);
63 }
64
65 static int _lpuart_serial_getc(struct lpuart_fsl *base)
66 {
67         while (!(__raw_readb(&base->us1) & (US1_RDRF | US1_OR)))
68                 WATCHDOG_RESET();
69
70         barrier();
71
72         return __raw_readb(&base->ud);
73 }
74
75 static void _lpuart_serial_putc(struct lpuart_fsl *base, const char c)
76 {
77         if (c == '\n')
78                 _lpuart_serial_putc(base, '\r');
79
80         while (!(__raw_readb(&base->us1) & US1_TDRE))
81                 WATCHDOG_RESET();
82
83         __raw_writeb(c, &base->ud);
84 }
85
86 /* Test whether a character is in the RX buffer */
87 static int _lpuart_serial_tstc(struct lpuart_fsl *base)
88 {
89         if (__raw_readb(&base->urcfifo) == 0)
90                 return 0;
91
92         return 1;
93 }
94
95 /*
96  * Initialise the serial port with the given baudrate. The settings
97  * are always 8 data bits, no parity, 1 stop bit, no start bits.
98  */
99 static int _lpuart_serial_init(struct lpuart_fsl *base)
100 {
101         u8 ctrl;
102
103         ctrl = __raw_readb(&base->uc2);
104         ctrl &= ~UC2_RE;
105         ctrl &= ~UC2_TE;
106         __raw_writeb(ctrl, &base->uc2);
107
108         __raw_writeb(0, &base->umodem);
109         __raw_writeb(0, &base->uc1);
110
111         /* Disable FIFO and flush buffer */
112         __raw_writeb(0x0, &base->upfifo);
113         __raw_writeb(0x0, &base->utwfifo);
114         __raw_writeb(0x1, &base->urwfifo);
115         __raw_writeb(CFIFO_TXFLUSH | CFIFO_RXFLUSH, &base->ucfifo);
116
117         /* provide data bits, parity, stop bit, etc */
118         _lpuart_serial_setbrg(base, gd->baudrate);
119
120         __raw_writeb(UC2_RE | UC2_TE, &base->uc2);
121
122         return 0;
123 }
124
125 static void lpuart_serial_setbrg(void)
126 {
127         _lpuart_serial_setbrg(base, gd->baudrate);
128 }
129
130 static int lpuart_serial_getc(void)
131 {
132         return _lpuart_serial_getc(base);
133 }
134
135 static void lpuart_serial_putc(const char c)
136 {
137         _lpuart_serial_putc(base, c);
138 }
139
140 static int lpuart_serial_tstc(void)
141 {
142         return _lpuart_serial_tstc(base);
143 }
144
145 static int lpuart_serial_init(void)
146 {
147         return _lpuart_serial_init(base);
148 }
149
150 static struct serial_device lpuart_serial_drv = {
151         .name = "lpuart_serial",
152         .start = lpuart_serial_init,
153         .stop = NULL,
154         .setbrg = lpuart_serial_setbrg,
155         .putc = lpuart_serial_putc,
156         .puts = default_serial_puts,
157         .getc = lpuart_serial_getc,
158         .tstc = lpuart_serial_tstc,
159 };
160 #else
161 static void _lpuart32_serial_setbrg(struct lpuart_fsl *base, int baudrate)
162 {
163         u32 clk = CONFIG_SYS_CLK_FREQ;
164         u32 sbr;
165
166         sbr = (clk / (16 * baudrate));
167
168         /* place adjustment later - n/32 BRFA */
169         out_be32(&base->baud, sbr);
170 }
171
172 static int _lpuart32_serial_getc(struct lpuart_fsl *base)
173 {
174         u32 stat;
175
176         while (((stat = in_be32(&base->stat)) & STAT_RDRF) == 0) {
177                 out_be32(&base->stat, STAT_FLAGS);
178                 WATCHDOG_RESET();
179         }
180
181         return in_be32(&base->data) & 0x3ff;
182 }
183
184 static void _lpuart32_serial_putc(struct lpuart_fsl *base, const char c)
185 {
186         if (c == '\n')
187                 _lpuart32_serial_putc(base, '\r');
188
189         while (!(in_be32(&base->stat) & STAT_TDRE))
190                 WATCHDOG_RESET();
191
192         out_be32(&base->data, c);
193 }
194
195 /* Test whether a character is in the RX buffer */
196 static int _lpuart32_serial_tstc(struct lpuart_fsl *base)
197 {
198         if ((in_be32(&base->water) >> 24) == 0)
199                 return 0;
200
201         return 1;
202 }
203
204 /*
205  * Initialise the serial port with the given baudrate. The settings
206  * are always 8 data bits, no parity, 1 stop bit, no start bits.
207  */
208 static int _lpuart32_serial_init(struct lpuart_fsl *base)
209 {
210         u8 ctrl;
211
212         ctrl = in_be32(&base->ctrl);
213         ctrl &= ~CTRL_RE;
214         ctrl &= ~CTRL_TE;
215         out_be32(&base->ctrl, ctrl);
216
217         out_be32(&base->modir, 0);
218         out_be32(&base->fifo, ~(FIFO_TXFE | FIFO_RXFE));
219
220         out_be32(&base->match, 0);
221
222         /* provide data bits, parity, stop bit, etc */
223         _lpuart32_serial_setbrg(base, gd->baudrate);
224
225         out_be32(&base->ctrl, CTRL_RE | CTRL_TE);
226
227         return 0;
228 }
229
230 static void lpuart32_serial_setbrg(void)
231 {
232         _lpuart32_serial_setbrg(base, gd->baudrate);
233 }
234
235 static int lpuart32_serial_getc(void)
236 {
237         return _lpuart32_serial_getc(base);
238 }
239
240 static void lpuart32_serial_putc(const char c)
241 {
242         _lpuart32_serial_putc(base, c);
243 }
244
245 static int lpuart32_serial_tstc(void)
246 {
247         return _lpuart32_serial_tstc(base);
248 }
249
250 static int lpuart32_serial_init(void)
251 {
252         return _lpuart32_serial_init(base);
253 }
254
255 static struct serial_device lpuart32_serial_drv = {
256         .name = "lpuart32_serial",
257         .start = lpuart32_serial_init,
258         .stop = NULL,
259         .setbrg = lpuart32_serial_setbrg,
260         .putc = lpuart32_serial_putc,
261         .puts = default_serial_puts,
262         .getc = lpuart32_serial_getc,
263         .tstc = lpuart32_serial_tstc,
264 };
265 #endif
266
267 void lpuart_serial_initialize(void)
268 {
269 #ifdef CONFIG_LPUART_32B_REG
270         serial_register(&lpuart32_serial_drv);
271 #else
272         serial_register(&lpuart_serial_drv);
273 #endif
274 }
275
276 __weak struct serial_device *default_serial_console(void)
277 {
278 #ifdef CONFIG_LPUART_32B_REG
279         return &lpuart32_serial_drv;
280 #else
281         return &lpuart_serial_drv;
282 #endif
283 }