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