Prepare v2023.10
[platform/kernel/u-boot.git] / drivers / serial / serial_sh.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * SuperH SCIF device driver.
4  * Copyright (C) 2013  Renesas Electronics Corporation
5  * Copyright (C) 2007,2008,2010, 2014 Nobuhiro Iwamatsu
6  * Copyright (C) 2002 - 2008  Paul Mundt
7  */
8
9 #include <common.h>
10 #include <errno.h>
11 #include <clk.h>
12 #include <dm.h>
13 #include <asm/global_data.h>
14 #include <asm/io.h>
15 #include <asm/processor.h>
16 #include <serial.h>
17 #include <linux/compiler.h>
18 #include <dm/platform_data/serial_sh.h>
19 #include <linux/delay.h>
20 #include "serial_sh.h"
21
22 DECLARE_GLOBAL_DATA_PTR;
23
24 #if defined(CONFIG_CPU_SH7780)
25 static int scif_rxfill(struct uart_port *port)
26 {
27         return sci_in(port, SCRFDR) & 0xff;
28 }
29 #elif defined(CONFIG_CPU_SH7763)
30 static int scif_rxfill(struct uart_port *port)
31 {
32         if ((port->mapbase == 0xffe00000) ||
33             (port->mapbase == 0xffe08000)) {
34                 /* SCIF0/1*/
35                 return sci_in(port, SCRFDR) & 0xff;
36         } else {
37                 /* SCIF2 */
38                 return sci_in(port, SCFDR) & SCIF2_RFDC_MASK;
39         }
40 }
41 #else
42 static int scif_rxfill(struct uart_port *port)
43 {
44         return sci_in(port, SCFDR) & SCIF_RFDC_MASK;
45 }
46 #endif
47
48 static void sh_serial_init_generic(struct uart_port *port)
49 {
50         sci_out(port, SCSCR , SCSCR_INIT(port));
51         sci_out(port, SCSCR , SCSCR_INIT(port));
52         sci_out(port, SCSMR, 0);
53         sci_out(port, SCSMR, 0);
54         sci_out(port, SCFCR, SCFCR_RFRST|SCFCR_TFRST);
55         sci_in(port, SCFCR);
56         sci_out(port, SCFCR, 0);
57 #if defined(CONFIG_RZA1)
58         sci_out(port, SCSPTR, 0x0003);
59 #endif
60
61         if (port->type == PORT_HSCIF)
62                 sci_out(port, HSSRR, HSSRR_SRE | HSSRR_SRCYC8);
63 }
64
65 static void
66 sh_serial_setbrg_generic(struct uart_port *port, int clk, int baudrate)
67 {
68         if (port->clk_mode == EXT_CLK) {
69                 unsigned short dl = DL_VALUE(baudrate, clk);
70                 sci_out(port, DL, dl);
71                 /* Need wait: Clock * 1/dl * 1/16 */
72                 udelay((1000000 * dl * 16 / clk) * 1000 + 1);
73         } else {
74                 sci_out(port, SCBRR, SCBRR_VALUE(baudrate, clk));
75         }
76 }
77
78 static void handle_error(struct uart_port *port)
79 {
80         sci_in(port, SCxSR);
81         sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
82         sci_in(port, SCLSR);
83         sci_out(port, SCLSR, 0x00);
84 }
85
86 static int serial_raw_putc(struct uart_port *port, const char c)
87 {
88         /* Tx fifo is empty */
89         if (!(sci_in(port, SCxSR) & SCxSR_TEND(port)))
90                 return -EAGAIN;
91
92         sci_out(port, SCxTDR, c);
93         sci_out(port, SCxSR, sci_in(port, SCxSR) & ~SCxSR_TEND(port));
94
95         return 0;
96 }
97
98 static int serial_rx_fifo_level(struct uart_port *port)
99 {
100         return scif_rxfill(port);
101 }
102
103 static int sh_serial_tstc_generic(struct uart_port *port)
104 {
105         if (sci_in(port, SCxSR) & SCIF_ERRORS) {
106                 handle_error(port);
107                 return 0;
108         }
109
110         return serial_rx_fifo_level(port) ? 1 : 0;
111 }
112
113 static int serial_getc_check(struct uart_port *port)
114 {
115         unsigned short status;
116
117         status = sci_in(port, SCxSR);
118
119         if (status & SCIF_ERRORS)
120                 handle_error(port);
121         if (sci_in(port, SCLSR) & SCxSR_ORER(port))
122                 handle_error(port);
123         status &= (SCIF_DR | SCxSR_RDxF(port));
124         if (status)
125                 return status;
126         return scif_rxfill(port);
127 }
128
129 static int sh_serial_getc_generic(struct uart_port *port)
130 {
131         unsigned short status;
132         char ch;
133
134         if (!serial_getc_check(port))
135                 return -EAGAIN;
136
137         ch = sci_in(port, SCxRDR);
138         status = sci_in(port, SCxSR);
139
140         sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
141
142         if (status & SCIF_ERRORS)
143                 handle_error(port);
144
145         if (sci_in(port, SCLSR) & SCxSR_ORER(port))
146                 handle_error(port);
147
148         return ch;
149 }
150
151 #if CONFIG_IS_ENABLED(DM_SERIAL)
152
153 static int sh_serial_pending(struct udevice *dev, bool input)
154 {
155         struct uart_port *priv = dev_get_priv(dev);
156
157         return sh_serial_tstc_generic(priv);
158 }
159
160 static int sh_serial_putc(struct udevice *dev, const char ch)
161 {
162         struct uart_port *priv = dev_get_priv(dev);
163
164         return serial_raw_putc(priv, ch);
165 }
166
167 static int sh_serial_getc(struct udevice *dev)
168 {
169         struct uart_port *priv = dev_get_priv(dev);
170
171         return sh_serial_getc_generic(priv);
172 }
173
174 static int sh_serial_setbrg(struct udevice *dev, int baudrate)
175 {
176         struct sh_serial_plat *plat = dev_get_plat(dev);
177         struct uart_port *priv = dev_get_priv(dev);
178
179         sh_serial_setbrg_generic(priv, plat->clk, baudrate);
180
181         return 0;
182 }
183
184 static int sh_serial_probe(struct udevice *dev)
185 {
186         struct sh_serial_plat *plat = dev_get_plat(dev);
187         struct uart_port *priv = dev_get_priv(dev);
188
189         priv->membase   = (unsigned char *)plat->base;
190         priv->mapbase   = plat->base;
191         priv->type      = plat->type;
192         priv->clk_mode  = plat->clk_mode;
193
194         sh_serial_init_generic(priv);
195
196         return 0;
197 }
198
199 static const struct dm_serial_ops sh_serial_ops = {
200         .putc = sh_serial_putc,
201         .pending = sh_serial_pending,
202         .getc = sh_serial_getc,
203         .setbrg = sh_serial_setbrg,
204 };
205
206 #if CONFIG_IS_ENABLED(OF_CONTROL)
207 static const struct udevice_id sh_serial_id[] ={
208         {.compatible = "renesas,sci", .data = PORT_SCI},
209         {.compatible = "renesas,scif", .data = PORT_SCIF},
210         {.compatible = "renesas,scifa", .data = PORT_SCIFA},
211         {.compatible = "renesas,hscif", .data = PORT_HSCIF},
212         {}
213 };
214
215 static int sh_serial_of_to_plat(struct udevice *dev)
216 {
217         struct sh_serial_plat *plat = dev_get_plat(dev);
218         struct clk sh_serial_clk;
219         fdt_addr_t addr;
220         int ret;
221
222         addr = dev_read_addr(dev);
223         if (!addr)
224                 return -EINVAL;
225
226         plat->base = addr;
227
228         ret = clk_get_by_name(dev, "fck", &sh_serial_clk);
229         if (!ret) {
230                 ret = clk_enable(&sh_serial_clk);
231                 if (!ret)
232                         plat->clk = clk_get_rate(&sh_serial_clk);
233         } else {
234                 plat->clk = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
235                                            "clock", 1);
236         }
237
238         plat->type = dev_get_driver_data(dev);
239         return 0;
240 }
241 #endif
242
243 U_BOOT_DRIVER(serial_sh) = {
244         .name   = "serial_sh",
245         .id     = UCLASS_SERIAL,
246         .of_match = of_match_ptr(sh_serial_id),
247         .of_to_plat = of_match_ptr(sh_serial_of_to_plat),
248         .plat_auto      = sizeof(struct sh_serial_plat),
249         .probe  = sh_serial_probe,
250         .ops    = &sh_serial_ops,
251 #if !CONFIG_IS_ENABLED(OF_CONTROL)
252         .flags  = DM_FLAG_PRE_RELOC,
253 #endif
254         .priv_auto      = sizeof(struct uart_port),
255 };
256 #endif
257
258 #if !CONFIG_IS_ENABLED(DM_SERIAL) || IS_ENABLED(CONFIG_DEBUG_UART_SCIF)
259
260 #if defined(CFG_SCIF_A)
261         #define SCIF_BASE_PORT  PORT_SCIFA
262 #elif defined(CFG_SCI)
263         #define SCIF_BASE_PORT  PORT_SCI
264 #elif defined(CFG_HSCIF)
265         #define SCIF_BASE_PORT  PORT_HSCIF
266 #else
267         #define SCIF_BASE_PORT  PORT_SCIF
268 #endif
269
270 static void sh_serial_init_nodm(struct uart_port *port)
271 {
272         sh_serial_init_generic(port);
273         serial_setbrg();
274 }
275
276 static void sh_serial_putc_nondm(struct uart_port *port, const char c)
277 {
278         if (c == '\n') {
279                 while (1) {
280                         if  (serial_raw_putc(port, '\r') != -EAGAIN)
281                                 break;
282                 }
283         }
284         while (1) {
285                 if  (serial_raw_putc(port, c) != -EAGAIN)
286                         break;
287         }
288 }
289 #endif
290
291 #if !CONFIG_IS_ENABLED(DM_SERIAL)
292 #if defined(CONFIG_CONS_SCIF0)
293 # define SCIF_BASE      SCIF0_BASE
294 #elif defined(CONFIG_CONS_SCIF1)
295 # define SCIF_BASE      SCIF1_BASE
296 #elif defined(CONFIG_CONS_SCIF2)
297 # define SCIF_BASE      SCIF2_BASE
298 #elif defined(CONFIG_CONS_SCIF3)
299 # define SCIF_BASE      SCIF3_BASE
300 #elif defined(CONFIG_CONS_SCIF4)
301 # define SCIF_BASE      SCIF4_BASE
302 #elif defined(CONFIG_CONS_SCIF5)
303 # define SCIF_BASE      SCIF5_BASE
304 #elif defined(CONFIG_CONS_SCIF6)
305 # define SCIF_BASE      SCIF6_BASE
306 #elif defined(CONFIG_CONS_SCIF7)
307 # define SCIF_BASE      SCIF7_BASE
308 #elif defined(CONFIG_CONS_SCIFA0)
309 # define SCIF_BASE      SCIFA0_BASE
310 #else
311 # error "Default SCIF doesn't set....."
312 #endif
313
314 static struct uart_port sh_sci = {
315         .membase        = (unsigned char *)SCIF_BASE,
316         .mapbase        = SCIF_BASE,
317         .type           = SCIF_BASE_PORT,
318 #ifdef CFG_SCIF_USE_EXT_CLK
319         .clk_mode =     EXT_CLK,
320 #endif
321 };
322
323 static void sh_serial_setbrg(void)
324 {
325         DECLARE_GLOBAL_DATA_PTR;
326         struct uart_port *port = &sh_sci;
327
328         sh_serial_setbrg_generic(port, CONFIG_SH_SCIF_CLK_FREQ, gd->baudrate);
329 }
330
331 static int sh_serial_init(void)
332 {
333         sh_serial_init_nodm(&sh_sci);
334
335         return 0;
336 }
337
338 static void sh_serial_putc(const char c)
339 {
340         sh_serial_putc_nondm(&sh_sci, c);
341 }
342
343 static int sh_serial_tstc(void)
344 {
345         struct uart_port *port = &sh_sci;
346
347         return sh_serial_tstc_generic(port);
348 }
349
350 static int sh_serial_getc(void)
351 {
352         struct uart_port *port = &sh_sci;
353         int ch;
354
355         while (1) {
356                 ch = sh_serial_getc_generic(port);
357                 if (ch != -EAGAIN)
358                         break;
359         }
360
361         return ch;
362 }
363
364 static struct serial_device sh_serial_drv = {
365         .name   = "sh_serial",
366         .start  = sh_serial_init,
367         .stop   = NULL,
368         .setbrg = sh_serial_setbrg,
369         .putc   = sh_serial_putc,
370         .puts   = default_serial_puts,
371         .getc   = sh_serial_getc,
372         .tstc   = sh_serial_tstc,
373 };
374
375 void sh_serial_initialize(void)
376 {
377         serial_register(&sh_serial_drv);
378 }
379
380 __weak struct serial_device *default_serial_console(void)
381 {
382         return &sh_serial_drv;
383 }
384 #endif /* CONFIG_DM_SERIAL */
385
386 #ifdef CONFIG_DEBUG_UART_SCIF
387 #include <debug_uart.h>
388
389 static struct uart_port debug_uart_sci = {
390         .membase        = (unsigned char *)CONFIG_DEBUG_UART_BASE,
391         .mapbase        = CONFIG_DEBUG_UART_BASE,
392         .type           = SCIF_BASE_PORT,
393 #ifdef CFG_SCIF_USE_EXT_CLK
394         .clk_mode =     EXT_CLK,
395 #endif
396 };
397
398 static inline void _debug_uart_init(void)
399 {
400         sh_serial_init_nodm(&debug_uart_sci);
401 }
402
403 static inline void _debug_uart_putc(int c)
404 {
405         sh_serial_putc_nondm(&debug_uart_sci, c);
406 }
407
408 DEBUG_UART_FUNCS
409
410 #endif