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