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