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