blob: 40381b57b08e4188925d113d89b570a0620b0fcd [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Patrice Chotard42d742b2017-02-21 13:37:07 +01002/*
3 * Support for Serial I/O using STMicroelectronics' on-chip ASC.
4 *
Patrice Chotard9e216242017-10-23 09:53:57 +02005 * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
Patrice Chotard5d9950d2020-12-02 18:47:30 +01006 * Author(s): Patrice Chotard, <patrice.chotard@foss.st.com> for STMicroelectronics.
Patrice Chotard42d742b2017-02-21 13:37:07 +01007 */
8
9#include <common.h>
10#include <dm.h>
Simon Glass0f2af882020-05-10 11:40:05 -060011#include <log.h>
Patrice Chotard42d742b2017-02-21 13:37:07 +010012#include <serial.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060013#include <asm/global_data.h>
Patrice Chotard42d742b2017-02-21 13:37:07 +010014#include <asm/io.h>
Simon Glass4dcacfc2020-05-10 11:40:13 -060015#include <linux/bitops.h>
Patrice Chotard42d742b2017-02-21 13:37:07 +010016
17DECLARE_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
30struct 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
43struct 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
70static 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
83static 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 */
131static 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 */
140static 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 */
153static 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 */
169static 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
Masahiro Yamadaa89b4de2020-07-17 14:36:48 +0900175 base = dev_read_addr(dev);
Patrice Chotard42d742b2017-02-21 13:37:07 +0100176 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
192static 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
199static const struct udevice_id sti_serial_of_match[] = {
200 { .compatible = "st,asc" },
201 { }
202};
203
204U_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,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700210 .priv_auto = sizeof(struct sti_asc_serial),
Patrice Chotard42d742b2017-02-21 13:37:07 +0100211};