1 // SPDX-License-Identifier: GPL-2.0+
3 * Support for Serial I/O using STMicroelectronics' on-chip ASC.
5 * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
14 DECLARE_GLOBAL_DATA_PTR;
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
25 #define STA_RBF BIT(0)
40 struct sti_asc_serial {
41 /* address of registers in physical memory */
42 struct sti_asc_uart *regs;
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))
53 * ASCBaudRate = ----------------
57 * baudrate * 16 * 2^16
58 * ASCBaudRate = ------------------------
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.
67 static int sti_asc_pending(struct udevice *dev, bool input)
69 struct sti_asc_serial *priv = dev_get_priv(dev);
70 struct sti_asc_uart *const uart = priv->regs;
73 status = readl(&uart->status);
75 return status & STA_RBF;
77 return status & STA_TF;
80 static int _sti_asc_serial_setbrg(struct sti_asc_uart *uart, int baudrate)
87 t = BAUDRATE_VAL_M0(9600);
91 t = BAUDRATE_VAL_M1(19200);
94 t = BAUDRATE_VAL_M1(38400);
97 t = BAUDRATE_VAL_M1(57600);
100 debug("ASC: unsupported baud rate: %d, using 115200 instead.\n",
103 t = BAUDRATE_VAL_M1(115200);
107 /* disable the baudrate generator */
108 val = readl(&uart->control);
109 writel(val & ~RUN, &uart->control);
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);
117 /* set baud generator mode */
121 /* finally, write value and enable ASC */
122 writel(val, &uart->control);
127 /* called to adjust baud-rate */
128 static int sti_asc_serial_setbrg(struct udevice *dev, int baudrate)
130 struct sti_asc_serial *priv = dev_get_priv(dev);
131 struct sti_asc_uart *const uart = priv->regs;
133 return _sti_asc_serial_setbrg(uart, baudrate);
136 /* blocking function, that returns next char */
137 static int sti_asc_serial_getc(struct udevice *dev)
139 struct sti_asc_serial *priv = dev_get_priv(dev);
140 struct sti_asc_uart *const uart = priv->regs;
142 /* polling wait: for a char to be read */
143 if (!sti_asc_pending(dev, true))
146 return readl(&uart->rxbuf);
149 /* write write out a single char */
150 static int sti_asc_serial_putc(struct udevice *dev, const char c)
152 struct sti_asc_serial *priv = dev_get_priv(dev);
153 struct sti_asc_uart *const uart = priv->regs;
155 /* wait till safe to write next char */
156 if (sti_asc_pending(dev, false))
159 /* finally, write next char */
160 writel(c, &uart->txbuf);
165 /* initialize the ASC */
166 static int sti_asc_serial_probe(struct udevice *dev)
168 struct sti_asc_serial *priv = dev_get_priv(dev);
172 base = devfdt_get_addr(dev);
173 if (base == FDT_ADDR_T_NONE)
176 priv->regs = (struct sti_asc_uart *)base;
177 sti_asc_serial_setbrg(dev, gd->baudrate);
180 * build up the value to be written to CONTROL
181 * set character length, bit stop number, odd parity
183 val = RXENABLE | RUN | MODE_8BIT | STOP_1BIT | PARITYODD;
184 writel(val, &priv->regs->control);
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,
196 static const struct udevice_id sti_serial_of_match[] = {
197 { .compatible = "st,asc" },
201 U_BOOT_DRIVER(serial_sti_asc) = {
202 .name = "serial_sti_asc",
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,