1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Support for Serial I/O using STMicroelectronics' on-chip ASC.
4  *
5  * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
6  * Author(s): Patrice Chotard, <patrice.chotard@foss.st.com> for STMicroelectronics.
7  */
8 
9 #include <dm.h>
10 #include <log.h>
11 #include <serial.h>
12 #include <asm/global_data.h>
13 #include <asm/io.h>
14 #include <linux/bitops.h>
15 
16 DECLARE_GLOBAL_DATA_PTR;
17 
18 #define BAUDMODE	0x00001000
19 #define RXENABLE	0x00000100
20 #define RUN		0x00000080
21 #define MODE		0x00000001
22 #define MODE_8BIT	0x0001
23 #define STOP_1BIT	0x0008
24 #define PARITYODD	0x0020
25 
26 #define STA_TF		BIT(9)
27 #define STA_RBF		BIT(0)
28 
29 struct sti_asc_uart {
30 	u32 baudrate;
31 	u32 txbuf;
32 	u32 rxbuf;
33 	u32 control;
34 	u32 inten;
35 	u32 status;
36 	u32 guardtime;
37 	u32 timeout;
38 	u32 txreset;
39 	u32 rxreset;
40 };
41 
42 struct sti_asc_serial {
43 	/* address of registers in physical memory */
44 	struct sti_asc_uart *regs;
45 };
46 
47 /* Values for the BAUDRATE Register */
48 #define PCLK			(200ul * 1000000ul)
49 #define BAUDRATE_VAL_M0(bps)	(PCLK / (16 * (bps)))
50 #define BAUDRATE_VAL_M1(bps)	((bps * (1 << 14)) + (1<<13)) / (PCLK/(1 << 6))
51 
52 /*
53  * MODE 0
54  *                       ICCLK
55  * ASCBaudRate =   ----------------
56  *                   baudrate * 16
57  *
58  * MODE 1
59  *                   baudrate * 16 * 2^16
60  * ASCBaudRate =   ------------------------
61  *                          ICCLK
62  *
63  * NOTE:
64  * Mode 1 should be used for baudrates of 19200, and above, as it
65  * has a lower deviation error than Mode 0 for higher frequencies.
66  * Mode 0 should be used for all baudrates below 19200.
67  */
68 
sti_asc_pending(struct udevice * dev,bool input)69 static int sti_asc_pending(struct udevice *dev, bool input)
70 {
71 	struct sti_asc_serial *priv = dev_get_priv(dev);
72 	struct sti_asc_uart *const uart = priv->regs;
73 	unsigned long status;
74 
75 	status = readl(&uart->status);
76 	if (input)
77 		return status & STA_RBF;
78 	else
79 		return status & STA_TF;
80 }
81 
_sti_asc_serial_setbrg(struct sti_asc_uart * uart,int baudrate)82 static int _sti_asc_serial_setbrg(struct sti_asc_uart *uart, int baudrate)
83 {
84 	unsigned long val;
85 	int t, mode = 1;
86 
87 	switch (baudrate) {
88 	case 9600:
89 		t = BAUDRATE_VAL_M0(9600);
90 		mode = 0;
91 		break;
92 	case 19200:
93 		t = BAUDRATE_VAL_M1(19200);
94 		break;
95 	case 38400:
96 		t = BAUDRATE_VAL_M1(38400);
97 		break;
98 	case 57600:
99 		t = BAUDRATE_VAL_M1(57600);
100 		break;
101 	default:
102 		debug("ASC: unsupported baud rate: %d, using 115200 instead.\n",
103 		      baudrate);
104 	case 115200:
105 		t = BAUDRATE_VAL_M1(115200);
106 		break;
107 	}
108 
109 	/* disable the baudrate generator */
110 	val = readl(&uart->control);
111 	writel(val & ~RUN, &uart->control);
112 
113 	/* set baud generator reload value */
114 	writel(t, &uart->baudrate);
115 	/* reset the RX & TX buffers */
116 	writel(1, &uart->txreset);
117 	writel(1, &uart->rxreset);
118 
119 	/* set baud generator mode */
120 	if (mode)
121 		val |= BAUDMODE;
122 
123 	/* finally, write value and enable ASC */
124 	writel(val, &uart->control);
125 
126 	return 0;
127 }
128 
129 /* called to adjust baud-rate */
sti_asc_serial_setbrg(struct udevice * dev,int baudrate)130 static int sti_asc_serial_setbrg(struct udevice *dev, int baudrate)
131 {
132 	struct sti_asc_serial *priv = dev_get_priv(dev);
133 	struct sti_asc_uart *const uart = priv->regs;
134 
135 	return _sti_asc_serial_setbrg(uart, baudrate);
136 }
137 
138 /* blocking function, that returns next char */
sti_asc_serial_getc(struct udevice * dev)139 static int sti_asc_serial_getc(struct udevice *dev)
140 {
141 	struct sti_asc_serial *priv = dev_get_priv(dev);
142 	struct sti_asc_uart *const uart = priv->regs;
143 
144 	/* polling wait: for a char to be read */
145 	if (!sti_asc_pending(dev, true))
146 		return -EAGAIN;
147 
148 	return readl(&uart->rxbuf);
149 }
150 
151 /* write write out a single char */
sti_asc_serial_putc(struct udevice * dev,const char c)152 static int sti_asc_serial_putc(struct udevice *dev, const char c)
153 {
154 	struct sti_asc_serial *priv = dev_get_priv(dev);
155 	struct sti_asc_uart *const uart = priv->regs;
156 
157 	/* wait till safe to write next char */
158 	if (sti_asc_pending(dev, false))
159 		return -EAGAIN;
160 
161 	/* finally, write next char */
162 	writel(c, &uart->txbuf);
163 
164 	return 0;
165 }
166 
167 /* initialize the ASC */
sti_asc_serial_probe(struct udevice * dev)168 static int sti_asc_serial_probe(struct udevice *dev)
169 {
170 	struct sti_asc_serial *priv = dev_get_priv(dev);
171 	unsigned long val;
172 	fdt_addr_t base;
173 
174 	base = dev_read_addr(dev);
175 	if (base == FDT_ADDR_T_NONE)
176 		return -EINVAL;
177 
178 	priv->regs = (struct sti_asc_uart *)base;
179 	sti_asc_serial_setbrg(dev, gd->baudrate);
180 
181 	/*
182 	 * build up the value to be written to CONTROL
183 	 * set character length, bit stop number, odd parity
184 	 */
185 	val = RXENABLE | RUN | MODE_8BIT | STOP_1BIT | PARITYODD;
186 	writel(val, &priv->regs->control);
187 
188 	return 0;
189 }
190 
191 static const struct dm_serial_ops sti_asc_serial_ops = {
192 	.putc = sti_asc_serial_putc,
193 	.pending = sti_asc_pending,
194 	.getc = sti_asc_serial_getc,
195 	.setbrg = sti_asc_serial_setbrg,
196 };
197 
198 static const struct udevice_id sti_serial_of_match[] = {
199 	{ .compatible = "st,asc" },
200 	{ }
201 };
202 
203 U_BOOT_DRIVER(serial_sti_asc) = {
204 	.name = "serial_sti_asc",
205 	.id = UCLASS_SERIAL,
206 	.of_match = sti_serial_of_match,
207 	.ops = &sti_asc_serial_ops,
208 	.probe = sti_asc_serial_probe,
209 	.priv_auto	= sizeof(struct sti_asc_serial),
210 };
211