xref: /rk3399_rockchip-uboot/drivers/serial/serial_sh.c (revision a89302cc7908de36e949b02013ac05ce5ef8b354)
129592ecbSNobuhiro Iwamatsu /*
229592ecbSNobuhiro Iwamatsu  * SuperH SCIF device driver.
348ca882cSNobuhiro Iwamatsu  * Copyright (C) 2013  Renesas Electronics Corporation
459088e4aSNobuhiro Iwamatsu  * Copyright (C) 2007,2008,2010, 2014 Nobuhiro Iwamatsu
53f6c8e36SNobuhiro Iwamatsu  * Copyright (C) 2002 - 2008  Paul Mundt
629592ecbSNobuhiro Iwamatsu  *
71a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
829592ecbSNobuhiro Iwamatsu  */
929592ecbSNobuhiro Iwamatsu 
1029592ecbSNobuhiro Iwamatsu #include <common.h>
1159088e4aSNobuhiro Iwamatsu #include <errno.h>
12*8171499dSMarek Vasut #include <clk.h>
1359088e4aSNobuhiro Iwamatsu #include <dm.h>
14fc83c927SJean-Christophe PLAGNIOL-VILLARD #include <asm/io.h>
1529592ecbSNobuhiro Iwamatsu #include <asm/processor.h>
168bdd7efaSMarek Vasut #include <serial.h>
178bdd7efaSMarek Vasut #include <linux/compiler.h>
1859088e4aSNobuhiro Iwamatsu #include <dm/platform_data/serial_sh.h>
1959088e4aSNobuhiro Iwamatsu #include "serial_sh.h"
2029592ecbSNobuhiro Iwamatsu 
21359787cfSYoshinori Sato DECLARE_GLOBAL_DATA_PTR;
22359787cfSYoshinori Sato 
233f6c8e36SNobuhiro Iwamatsu #if defined(CONFIG_CPU_SH7760) || \
243f6c8e36SNobuhiro Iwamatsu 	defined(CONFIG_CPU_SH7780) || \
253f6c8e36SNobuhiro Iwamatsu 	defined(CONFIG_CPU_SH7785) || \
263f6c8e36SNobuhiro Iwamatsu 	defined(CONFIG_CPU_SH7786)
scif_rxfill(struct uart_port * port)273f6c8e36SNobuhiro Iwamatsu static int scif_rxfill(struct uart_port *port)
283f6c8e36SNobuhiro Iwamatsu {
293f6c8e36SNobuhiro Iwamatsu 	return sci_in(port, SCRFDR) & 0xff;
303f6c8e36SNobuhiro Iwamatsu }
313f6c8e36SNobuhiro Iwamatsu #elif defined(CONFIG_CPU_SH7763)
scif_rxfill(struct uart_port * port)323f6c8e36SNobuhiro Iwamatsu static int scif_rxfill(struct uart_port *port)
333f6c8e36SNobuhiro Iwamatsu {
343f6c8e36SNobuhiro Iwamatsu 	if ((port->mapbase == 0xffe00000) ||
353f6c8e36SNobuhiro Iwamatsu 	    (port->mapbase == 0xffe08000)) {
363f6c8e36SNobuhiro Iwamatsu 		/* SCIF0/1*/
373f6c8e36SNobuhiro Iwamatsu 		return sci_in(port, SCRFDR) & 0xff;
383f6c8e36SNobuhiro Iwamatsu 	} else {
393f6c8e36SNobuhiro Iwamatsu 		/* SCIF2 */
403f6c8e36SNobuhiro Iwamatsu 		return sci_in(port, SCFDR) & SCIF2_RFDC_MASK;
413f6c8e36SNobuhiro Iwamatsu 	}
423f6c8e36SNobuhiro Iwamatsu }
433f6c8e36SNobuhiro Iwamatsu #elif defined(CONFIG_ARCH_SH7372)
scif_rxfill(struct uart_port * port)443f6c8e36SNobuhiro Iwamatsu static int scif_rxfill(struct uart_port *port)
453f6c8e36SNobuhiro Iwamatsu {
463f6c8e36SNobuhiro Iwamatsu 	if (port->type == PORT_SCIFA)
473f6c8e36SNobuhiro Iwamatsu 		return sci_in(port, SCFDR) & SCIF_RFDC_MASK;
483f6c8e36SNobuhiro Iwamatsu 	else
493f6c8e36SNobuhiro Iwamatsu 		return sci_in(port, SCRFDR);
503f6c8e36SNobuhiro Iwamatsu }
513f6c8e36SNobuhiro Iwamatsu #else
scif_rxfill(struct uart_port * port)523f6c8e36SNobuhiro Iwamatsu static int scif_rxfill(struct uart_port *port)
533f6c8e36SNobuhiro Iwamatsu {
543f6c8e36SNobuhiro Iwamatsu 	return sci_in(port, SCFDR) & SCIF_RFDC_MASK;
553f6c8e36SNobuhiro Iwamatsu }
563f6c8e36SNobuhiro Iwamatsu #endif
573f6c8e36SNobuhiro Iwamatsu 
sh_serial_init_generic(struct uart_port * port)5859088e4aSNobuhiro Iwamatsu static void sh_serial_init_generic(struct uart_port *port)
5929592ecbSNobuhiro Iwamatsu {
6059088e4aSNobuhiro Iwamatsu 	sci_out(port, SCSCR , SCSCR_INIT(port));
6159088e4aSNobuhiro Iwamatsu 	sci_out(port, SCSCR , SCSCR_INIT(port));
6259088e4aSNobuhiro Iwamatsu 	sci_out(port, SCSMR, 0);
6359088e4aSNobuhiro Iwamatsu 	sci_out(port, SCSMR, 0);
6459088e4aSNobuhiro Iwamatsu 	sci_out(port, SCFCR, SCFCR_RFRST|SCFCR_TFRST);
6559088e4aSNobuhiro Iwamatsu 	sci_in(port, SCFCR);
6659088e4aSNobuhiro Iwamatsu 	sci_out(port, SCFCR, 0);
6729592ecbSNobuhiro Iwamatsu }
6829592ecbSNobuhiro Iwamatsu 
6959088e4aSNobuhiro Iwamatsu static void
sh_serial_setbrg_generic(struct uart_port * port,int clk,int baudrate)7059088e4aSNobuhiro Iwamatsu sh_serial_setbrg_generic(struct uart_port *port, int clk, int baudrate)
717c791b3fSTetsuyuki Kobayashi {
7259088e4aSNobuhiro Iwamatsu 	if (port->clk_mode == EXT_CLK) {
7359088e4aSNobuhiro Iwamatsu 		unsigned short dl = DL_VALUE(baudrate, clk);
7459088e4aSNobuhiro Iwamatsu 		sci_out(port, DL, dl);
7589f99a62SNobuhiro Iwamatsu 		/* Need wait: Clock * 1/dl * 1/16 */
7659088e4aSNobuhiro Iwamatsu 		udelay((1000000 * dl * 16 / clk) * 1000 + 1);
7759088e4aSNobuhiro Iwamatsu 	} else {
7859088e4aSNobuhiro Iwamatsu 		sci_out(port, SCBRR, SCBRR_VALUE(baudrate, clk));
7959088e4aSNobuhiro Iwamatsu 	}
807c791b3fSTetsuyuki Kobayashi }
817c791b3fSTetsuyuki Kobayashi 
handle_error(struct uart_port * port)8259088e4aSNobuhiro Iwamatsu static void handle_error(struct uart_port *port)
8329592ecbSNobuhiro Iwamatsu {
8459088e4aSNobuhiro Iwamatsu 	sci_in(port, SCxSR);
8559088e4aSNobuhiro Iwamatsu 	sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
8659088e4aSNobuhiro Iwamatsu 	sci_in(port, SCLSR);
8759088e4aSNobuhiro Iwamatsu 	sci_out(port, SCLSR, 0x00);
8859088e4aSNobuhiro Iwamatsu }
8959088e4aSNobuhiro Iwamatsu 
serial_raw_putc(struct uart_port * port,const char c)9059088e4aSNobuhiro Iwamatsu static int serial_raw_putc(struct uart_port *port, const char c)
9159088e4aSNobuhiro Iwamatsu {
923f6c8e36SNobuhiro Iwamatsu 	/* Tx fifo is empty */
9359088e4aSNobuhiro Iwamatsu 	if (!(sci_in(port, SCxSR) & SCxSR_TEND(port)))
9459088e4aSNobuhiro Iwamatsu 		return -EAGAIN;
9529592ecbSNobuhiro Iwamatsu 
9659088e4aSNobuhiro Iwamatsu 	sci_out(port, SCxTDR, c);
9759088e4aSNobuhiro Iwamatsu 	sci_out(port, SCxSR, sci_in(port, SCxSR) & ~SCxSR_TEND(port));
9829592ecbSNobuhiro Iwamatsu 
997c791b3fSTetsuyuki Kobayashi 	return 0;
1007c791b3fSTetsuyuki Kobayashi }
1017c791b3fSTetsuyuki Kobayashi 
serial_rx_fifo_level(struct uart_port * port)10259088e4aSNobuhiro Iwamatsu static int serial_rx_fifo_level(struct uart_port *port)
10359088e4aSNobuhiro Iwamatsu {
10459088e4aSNobuhiro Iwamatsu 	return scif_rxfill(port);
10529592ecbSNobuhiro Iwamatsu }
10629592ecbSNobuhiro Iwamatsu 
sh_serial_tstc_generic(struct uart_port * port)10759088e4aSNobuhiro Iwamatsu static int sh_serial_tstc_generic(struct uart_port *port)
10859088e4aSNobuhiro Iwamatsu {
10959088e4aSNobuhiro Iwamatsu 	if (sci_in(port, SCxSR) & SCIF_ERRORS) {
11059088e4aSNobuhiro Iwamatsu 		handle_error(port);
11159088e4aSNobuhiro Iwamatsu 		return 0;
11259088e4aSNobuhiro Iwamatsu 	}
11329592ecbSNobuhiro Iwamatsu 
11459088e4aSNobuhiro Iwamatsu 	return serial_rx_fifo_level(port) ? 1 : 0;
11559088e4aSNobuhiro Iwamatsu }
11659088e4aSNobuhiro Iwamatsu 
serial_getc_check(struct uart_port * port)11759088e4aSNobuhiro Iwamatsu static int serial_getc_check(struct uart_port *port)
11808c5fabeSNobuhiro Iwamatsu {
11929592ecbSNobuhiro Iwamatsu 	unsigned short status;
12029592ecbSNobuhiro Iwamatsu 
12159088e4aSNobuhiro Iwamatsu 	status = sci_in(port, SCxSR);
12229592ecbSNobuhiro Iwamatsu 
1233f6c8e36SNobuhiro Iwamatsu 	if (status & SCIF_ERRORS)
12459088e4aSNobuhiro Iwamatsu 		handle_error(port);
12559088e4aSNobuhiro Iwamatsu 	if (sci_in(port, SCLSR) & SCxSR_ORER(port))
12659088e4aSNobuhiro Iwamatsu 		handle_error(port);
12759088e4aSNobuhiro Iwamatsu 	return status & (SCIF_DR | SCxSR_RDxF(port));
12829592ecbSNobuhiro Iwamatsu }
12929592ecbSNobuhiro Iwamatsu 
sh_serial_getc_generic(struct uart_port * port)13059088e4aSNobuhiro Iwamatsu static int sh_serial_getc_generic(struct uart_port *port)
13129592ecbSNobuhiro Iwamatsu {
13229592ecbSNobuhiro Iwamatsu 	unsigned short status;
13329592ecbSNobuhiro Iwamatsu 	char ch;
134ab09f433SNobuhiro Iwamatsu 
13559088e4aSNobuhiro Iwamatsu 	if (!serial_getc_check(port))
13659088e4aSNobuhiro Iwamatsu 		return -EAGAIN;
13729592ecbSNobuhiro Iwamatsu 
13859088e4aSNobuhiro Iwamatsu 	ch = sci_in(port, SCxRDR);
13959088e4aSNobuhiro Iwamatsu 	status = sci_in(port, SCxSR);
14029592ecbSNobuhiro Iwamatsu 
14159088e4aSNobuhiro Iwamatsu 	sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
14229592ecbSNobuhiro Iwamatsu 
1433f6c8e36SNobuhiro Iwamatsu 	if (status & SCIF_ERRORS)
14459088e4aSNobuhiro Iwamatsu 		handle_error(port);
14529592ecbSNobuhiro Iwamatsu 
14659088e4aSNobuhiro Iwamatsu 	if (sci_in(port, SCLSR) & SCxSR_ORER(port))
14759088e4aSNobuhiro Iwamatsu 		handle_error(port);
14859088e4aSNobuhiro Iwamatsu 
14959088e4aSNobuhiro Iwamatsu 	return ch;
15059088e4aSNobuhiro Iwamatsu }
15159088e4aSNobuhiro Iwamatsu 
15259088e4aSNobuhiro Iwamatsu #ifdef CONFIG_DM_SERIAL
15359088e4aSNobuhiro Iwamatsu 
sh_serial_pending(struct udevice * dev,bool input)15459088e4aSNobuhiro Iwamatsu static int sh_serial_pending(struct udevice *dev, bool input)
15559088e4aSNobuhiro Iwamatsu {
15659088e4aSNobuhiro Iwamatsu 	struct uart_port *priv = dev_get_priv(dev);
15759088e4aSNobuhiro Iwamatsu 
15859088e4aSNobuhiro Iwamatsu 	return sh_serial_tstc_generic(priv);
15959088e4aSNobuhiro Iwamatsu }
16059088e4aSNobuhiro Iwamatsu 
sh_serial_putc(struct udevice * dev,const char ch)16159088e4aSNobuhiro Iwamatsu static int sh_serial_putc(struct udevice *dev, const char ch)
16259088e4aSNobuhiro Iwamatsu {
16359088e4aSNobuhiro Iwamatsu 	struct uart_port *priv = dev_get_priv(dev);
16459088e4aSNobuhiro Iwamatsu 
16559088e4aSNobuhiro Iwamatsu 	return serial_raw_putc(priv, ch);
16659088e4aSNobuhiro Iwamatsu }
16759088e4aSNobuhiro Iwamatsu 
sh_serial_getc(struct udevice * dev)16859088e4aSNobuhiro Iwamatsu static int sh_serial_getc(struct udevice *dev)
16959088e4aSNobuhiro Iwamatsu {
17059088e4aSNobuhiro Iwamatsu 	struct uart_port *priv = dev_get_priv(dev);
17159088e4aSNobuhiro Iwamatsu 
17259088e4aSNobuhiro Iwamatsu 	return sh_serial_getc_generic(priv);
17359088e4aSNobuhiro Iwamatsu }
17459088e4aSNobuhiro Iwamatsu 
sh_serial_setbrg(struct udevice * dev,int baudrate)17559088e4aSNobuhiro Iwamatsu static int sh_serial_setbrg(struct udevice *dev, int baudrate)
17659088e4aSNobuhiro Iwamatsu {
17759088e4aSNobuhiro Iwamatsu 	struct sh_serial_platdata *plat = dev_get_platdata(dev);
17859088e4aSNobuhiro Iwamatsu 	struct uart_port *priv = dev_get_priv(dev);
17959088e4aSNobuhiro Iwamatsu 
18059088e4aSNobuhiro Iwamatsu 	sh_serial_setbrg_generic(priv, plat->clk, baudrate);
18159088e4aSNobuhiro Iwamatsu 
18259088e4aSNobuhiro Iwamatsu 	return 0;
18359088e4aSNobuhiro Iwamatsu }
18459088e4aSNobuhiro Iwamatsu 
sh_serial_probe(struct udevice * dev)18559088e4aSNobuhiro Iwamatsu static int sh_serial_probe(struct udevice *dev)
18659088e4aSNobuhiro Iwamatsu {
18759088e4aSNobuhiro Iwamatsu 	struct sh_serial_platdata *plat = dev_get_platdata(dev);
18859088e4aSNobuhiro Iwamatsu 	struct uart_port *priv = dev_get_priv(dev);
18959088e4aSNobuhiro Iwamatsu 
19059088e4aSNobuhiro Iwamatsu 	priv->membase	= (unsigned char *)plat->base;
19159088e4aSNobuhiro Iwamatsu 	priv->mapbase	= plat->base;
19259088e4aSNobuhiro Iwamatsu 	priv->type	= plat->type;
19359088e4aSNobuhiro Iwamatsu 	priv->clk_mode	= plat->clk_mode;
19459088e4aSNobuhiro Iwamatsu 
19559088e4aSNobuhiro Iwamatsu 	sh_serial_init_generic(priv);
19659088e4aSNobuhiro Iwamatsu 
19759088e4aSNobuhiro Iwamatsu 	return 0;
19859088e4aSNobuhiro Iwamatsu }
19959088e4aSNobuhiro Iwamatsu 
20059088e4aSNobuhiro Iwamatsu static const struct dm_serial_ops sh_serial_ops = {
20159088e4aSNobuhiro Iwamatsu 	.putc = sh_serial_putc,
20259088e4aSNobuhiro Iwamatsu 	.pending = sh_serial_pending,
20359088e4aSNobuhiro Iwamatsu 	.getc = sh_serial_getc,
20459088e4aSNobuhiro Iwamatsu 	.setbrg = sh_serial_setbrg,
20559088e4aSNobuhiro Iwamatsu };
20659088e4aSNobuhiro Iwamatsu 
207359787cfSYoshinori Sato #ifdef CONFIG_OF_CONTROL
208359787cfSYoshinori Sato static const struct udevice_id sh_serial_id[] ={
209747431b9SYoshinori Sato 	{.compatible = "renesas,sci", .data = PORT_SCI},
210359787cfSYoshinori Sato 	{.compatible = "renesas,scif", .data = PORT_SCIF},
211359787cfSYoshinori Sato 	{.compatible = "renesas,scifa", .data = PORT_SCIFA},
212359787cfSYoshinori Sato 	{}
213359787cfSYoshinori Sato };
214359787cfSYoshinori Sato 
sh_serial_ofdata_to_platdata(struct udevice * dev)215359787cfSYoshinori Sato static int sh_serial_ofdata_to_platdata(struct udevice *dev)
216359787cfSYoshinori Sato {
217359787cfSYoshinori Sato 	struct sh_serial_platdata *plat = dev_get_platdata(dev);
218*8171499dSMarek Vasut 	struct clk sh_serial_clk;
219359787cfSYoshinori Sato 	fdt_addr_t addr;
220*8171499dSMarek Vasut 	int ret;
221359787cfSYoshinori Sato 
222e160f7d4SSimon Glass 	addr = fdtdec_get_addr(gd->fdt_blob, dev_of_offset(dev), "reg");
223359787cfSYoshinori Sato 	if (addr == FDT_ADDR_T_NONE)
224359787cfSYoshinori Sato 		return -EINVAL;
225359787cfSYoshinori Sato 
226359787cfSYoshinori Sato 	plat->base = addr;
227*8171499dSMarek Vasut 
228*8171499dSMarek Vasut 	ret = clk_get_by_name(dev, "fck", &sh_serial_clk);
229*8171499dSMarek Vasut 	if (!ret)
230*8171499dSMarek Vasut 		plat->clk = clk_get_rate(&sh_serial_clk);
231*8171499dSMarek Vasut 	else
232*8171499dSMarek Vasut 		plat->clk = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
233*8171499dSMarek Vasut 					   "clock", 1);
234*8171499dSMarek Vasut 
235359787cfSYoshinori Sato 	plat->type = dev_get_driver_data(dev);
236359787cfSYoshinori Sato 	return 0;
237359787cfSYoshinori Sato }
238359787cfSYoshinori Sato #endif
239359787cfSYoshinori Sato 
24059088e4aSNobuhiro Iwamatsu U_BOOT_DRIVER(serial_sh) = {
24159088e4aSNobuhiro Iwamatsu 	.name	= "serial_sh",
24259088e4aSNobuhiro Iwamatsu 	.id	= UCLASS_SERIAL,
243359787cfSYoshinori Sato 	.of_match = of_match_ptr(sh_serial_id),
244359787cfSYoshinori Sato 	.ofdata_to_platdata = of_match_ptr(sh_serial_ofdata_to_platdata),
245359787cfSYoshinori Sato 	.platdata_auto_alloc_size = sizeof(struct sh_serial_platdata),
24659088e4aSNobuhiro Iwamatsu 	.probe	= sh_serial_probe,
24759088e4aSNobuhiro Iwamatsu 	.ops	= &sh_serial_ops,
24859088e4aSNobuhiro Iwamatsu 	.flags	= DM_FLAG_PRE_RELOC,
24959088e4aSNobuhiro Iwamatsu 	.priv_auto_alloc_size = sizeof(struct uart_port),
25059088e4aSNobuhiro Iwamatsu };
25159088e4aSNobuhiro Iwamatsu 
25259088e4aSNobuhiro Iwamatsu #else /* CONFIG_DM_SERIAL */
25359088e4aSNobuhiro Iwamatsu 
25459088e4aSNobuhiro Iwamatsu #if defined(CONFIG_CONS_SCIF0)
25559088e4aSNobuhiro Iwamatsu # define SCIF_BASE	SCIF0_BASE
25659088e4aSNobuhiro Iwamatsu #elif defined(CONFIG_CONS_SCIF1)
25759088e4aSNobuhiro Iwamatsu # define SCIF_BASE	SCIF1_BASE
25859088e4aSNobuhiro Iwamatsu #elif defined(CONFIG_CONS_SCIF2)
25959088e4aSNobuhiro Iwamatsu # define SCIF_BASE	SCIF2_BASE
26059088e4aSNobuhiro Iwamatsu #elif defined(CONFIG_CONS_SCIF3)
26159088e4aSNobuhiro Iwamatsu # define SCIF_BASE	SCIF3_BASE
26259088e4aSNobuhiro Iwamatsu #elif defined(CONFIG_CONS_SCIF4)
26359088e4aSNobuhiro Iwamatsu # define SCIF_BASE	SCIF4_BASE
26459088e4aSNobuhiro Iwamatsu #elif defined(CONFIG_CONS_SCIF5)
26559088e4aSNobuhiro Iwamatsu # define SCIF_BASE	SCIF5_BASE
26659088e4aSNobuhiro Iwamatsu #elif defined(CONFIG_CONS_SCIF6)
26759088e4aSNobuhiro Iwamatsu # define SCIF_BASE	SCIF6_BASE
26859088e4aSNobuhiro Iwamatsu #elif defined(CONFIG_CONS_SCIF7)
26959088e4aSNobuhiro Iwamatsu # define SCIF_BASE	SCIF7_BASE
27059088e4aSNobuhiro Iwamatsu #else
27159088e4aSNobuhiro Iwamatsu # error "Default SCIF doesn't set....."
27259088e4aSNobuhiro Iwamatsu #endif
27359088e4aSNobuhiro Iwamatsu 
27459088e4aSNobuhiro Iwamatsu #if defined(CONFIG_SCIF_A)
27559088e4aSNobuhiro Iwamatsu 	#define SCIF_BASE_PORT	PORT_SCIFA
276747431b9SYoshinori Sato #elif defined(CONFIG_SCI)
277747431b9SYoshinori Sato 	#define SCIF_BASE_PORT  PORT_SCI
27859088e4aSNobuhiro Iwamatsu #else
27959088e4aSNobuhiro Iwamatsu 	#define SCIF_BASE_PORT	PORT_SCIF
28059088e4aSNobuhiro Iwamatsu #endif
28159088e4aSNobuhiro Iwamatsu 
28259088e4aSNobuhiro Iwamatsu static struct uart_port sh_sci = {
28359088e4aSNobuhiro Iwamatsu 	.membase	= (unsigned char *)SCIF_BASE,
28459088e4aSNobuhiro Iwamatsu 	.mapbase	= SCIF_BASE,
28559088e4aSNobuhiro Iwamatsu 	.type		= SCIF_BASE_PORT,
28659088e4aSNobuhiro Iwamatsu #ifdef CONFIG_SCIF_USE_EXT_CLK
28759088e4aSNobuhiro Iwamatsu 	.clk_mode =	EXT_CLK,
28859088e4aSNobuhiro Iwamatsu #endif
28959088e4aSNobuhiro Iwamatsu };
29059088e4aSNobuhiro Iwamatsu 
sh_serial_setbrg(void)29159088e4aSNobuhiro Iwamatsu static void sh_serial_setbrg(void)
29259088e4aSNobuhiro Iwamatsu {
29359088e4aSNobuhiro Iwamatsu 	DECLARE_GLOBAL_DATA_PTR;
29459088e4aSNobuhiro Iwamatsu 	struct uart_port *port = &sh_sci;
29559088e4aSNobuhiro Iwamatsu 
29659088e4aSNobuhiro Iwamatsu 	sh_serial_setbrg_generic(port, CONFIG_SH_SCIF_CLK_FREQ, gd->baudrate);
29759088e4aSNobuhiro Iwamatsu }
29859088e4aSNobuhiro Iwamatsu 
sh_serial_init(void)29959088e4aSNobuhiro Iwamatsu static int sh_serial_init(void)
30059088e4aSNobuhiro Iwamatsu {
30159088e4aSNobuhiro Iwamatsu 	struct uart_port *port = &sh_sci;
30259088e4aSNobuhiro Iwamatsu 
30359088e4aSNobuhiro Iwamatsu 	sh_serial_init_generic(port);
30459088e4aSNobuhiro Iwamatsu 	serial_setbrg();
30559088e4aSNobuhiro Iwamatsu 
30659088e4aSNobuhiro Iwamatsu 	return 0;
30759088e4aSNobuhiro Iwamatsu }
30859088e4aSNobuhiro Iwamatsu 
sh_serial_putc(const char c)30959088e4aSNobuhiro Iwamatsu static void sh_serial_putc(const char c)
31059088e4aSNobuhiro Iwamatsu {
31159088e4aSNobuhiro Iwamatsu 	struct uart_port *port = &sh_sci;
31259088e4aSNobuhiro Iwamatsu 
31359088e4aSNobuhiro Iwamatsu 	if (c == '\n') {
31459088e4aSNobuhiro Iwamatsu 		while (1) {
31559088e4aSNobuhiro Iwamatsu 			if  (serial_raw_putc(port, '\r') != -EAGAIN)
31659088e4aSNobuhiro Iwamatsu 				break;
31759088e4aSNobuhiro Iwamatsu 		}
31859088e4aSNobuhiro Iwamatsu 	}
31959088e4aSNobuhiro Iwamatsu 	while (1) {
32059088e4aSNobuhiro Iwamatsu 		if  (serial_raw_putc(port, c) != -EAGAIN)
32159088e4aSNobuhiro Iwamatsu 			break;
32259088e4aSNobuhiro Iwamatsu 	}
32359088e4aSNobuhiro Iwamatsu }
32459088e4aSNobuhiro Iwamatsu 
sh_serial_tstc(void)32559088e4aSNobuhiro Iwamatsu static int sh_serial_tstc(void)
32659088e4aSNobuhiro Iwamatsu {
32759088e4aSNobuhiro Iwamatsu 	struct uart_port *port = &sh_sci;
32859088e4aSNobuhiro Iwamatsu 
32959088e4aSNobuhiro Iwamatsu 	return sh_serial_tstc_generic(port);
33059088e4aSNobuhiro Iwamatsu }
33159088e4aSNobuhiro Iwamatsu 
sh_serial_getc(void)33259088e4aSNobuhiro Iwamatsu static int sh_serial_getc(void)
33359088e4aSNobuhiro Iwamatsu {
33459088e4aSNobuhiro Iwamatsu 	struct uart_port *port = &sh_sci;
33559088e4aSNobuhiro Iwamatsu 	int ch;
33659088e4aSNobuhiro Iwamatsu 
33759088e4aSNobuhiro Iwamatsu 	while (1) {
33859088e4aSNobuhiro Iwamatsu 		ch = sh_serial_getc_generic(port);
33959088e4aSNobuhiro Iwamatsu 		if (ch != -EAGAIN)
34059088e4aSNobuhiro Iwamatsu 			break;
34159088e4aSNobuhiro Iwamatsu 	}
34259088e4aSNobuhiro Iwamatsu 
34329592ecbSNobuhiro Iwamatsu 	return ch;
34429592ecbSNobuhiro Iwamatsu }
3458bdd7efaSMarek Vasut 
3468bdd7efaSMarek Vasut static struct serial_device sh_serial_drv = {
3478bdd7efaSMarek Vasut 	.name	= "sh_serial",
3488bdd7efaSMarek Vasut 	.start	= sh_serial_init,
3498bdd7efaSMarek Vasut 	.stop	= NULL,
3508bdd7efaSMarek Vasut 	.setbrg	= sh_serial_setbrg,
3518bdd7efaSMarek Vasut 	.putc	= sh_serial_putc,
352ec3fd689SMarek Vasut 	.puts	= default_serial_puts,
3538bdd7efaSMarek Vasut 	.getc	= sh_serial_getc,
3548bdd7efaSMarek Vasut 	.tstc	= sh_serial_tstc,
3558bdd7efaSMarek Vasut };
3568bdd7efaSMarek Vasut 
sh_serial_initialize(void)3578bdd7efaSMarek Vasut void sh_serial_initialize(void)
3588bdd7efaSMarek Vasut {
3598bdd7efaSMarek Vasut 	serial_register(&sh_serial_drv);
3608bdd7efaSMarek Vasut }
3618bdd7efaSMarek Vasut 
default_serial_console(void)3628bdd7efaSMarek Vasut __weak struct serial_device *default_serial_console(void)
3638bdd7efaSMarek Vasut {
3648bdd7efaSMarek Vasut 	return &sh_serial_drv;
3658bdd7efaSMarek Vasut }
36659088e4aSNobuhiro Iwamatsu #endif /* CONFIG_DM_SERIAL */
367